Giter Site home page Giter Site logo

jamsvgimage's Introduction

JAMSVGImage

A set of classes for parsing and rendering resolution-independent SVG (Scalable Vector Graphics) files in your iOS application.

The nerdy details: JAMSVGImage parses SVG files and transforms all 'path' elements into a collection of stylized UIBezierPath objects which are rendered (at any scale) at the device's native resolution at runtime. SVG files are typically produced with 2D drawing applications such as Adobe Illustrator or Inkscape.

JAMSVGImageView Example

Why SVG?

Look: they look great no matter if they are scaled up or down since SVG images are described with mathematical curves rather than discrete pixels as with PNG or JPG.

Convenience: there's no need to generate @2x and @3x versions of your art assets. A single SVG is all you need.

File Size: SVG and SVGZ (gzipped SVG) are typically a fraction of the file size of a set of PNG or JPG art assets.

Usage

Use JAMSVGImage and JAMSVGImageView in places where you would normally use UIImage, UIImageView, or where you would programmatically draw your own graphics. There are a few ways to use these classes.

JAMSVGImageView is IBDesignable and IBInspectable so you can drag a UIView to your layout in Interface Builder, set the class type to "JAMSVGImageView", and then type the name of the SVG image like so:

JAMSVGImageView Example

Secondly, you can programmatically alloc and init a new JAMSVGImageView with a JAMSVGImage, and add it to your view heirarchy

JAMSVGImage *tiger = [JAMSVGImage imageNamed:@"tiger"];
JAMSVGImageView *tigerImageView = [JAMSVGImageView.alloc initWithSVGImage:tiger];
tigerImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:tigerImageView];

The SVG image will draw at high resolution no matter what the density or scale of the device's display.

Third, you can create a JAMSVGImage instance and use the drawInCurrentContext method in your current graphics context like so:

JAMSVGImage *tiger = [JAMSVGImage imageNamed:@"tiger"];
[tiger drawInCurrentContext];

You can also call [tiger image] or .CGImage to get a raster UIImage or CGImageRef and use that anywhere you would use a UIImage or CGImageRef. You can set the scale before getting the image if you need it bigger or smaller, or you can pass in a rect to have the SVG rendered in that rect at the proper scale for your device (whether it's a @1x, @2x, or @3x screen):

[self.button setBackgroundImage:[[JAMSVGImage imageNamed:@"fancyButton"] imageAtSize:self.button.bounds.size] forState:UIControlStateNormal];

Last, there is a JAMSVGButton subclass of UIButton that allows setting the four button states to SVG files via Interface Builder.

JAMSVGButton Example

Supported SVG Shape Features & Appearance:

File Formats:

  • SVG 1.1 documents either normal or gzipped (.svgz)

Shape Primitives:

  • Circle
  • Ellipse
  • Rectangle
  • Line
  • Polyline
  • Bezier Path
  • Elliptical Arc

Shape Appearance:

  • Fill Color
  • Fill Rules
  • Gradient Fill
  • Opacity
  • Stroke Color
  • Stroke Weight
  • Line Dashes
  • Line Join/Cap (Butt/Round/Miter)
  • Affine Transformations
  • Inherited Group Level Appearance

SVG Document Properties:

  • viewBox
  • width, height

Note on using JAMSVGImage with Cocoapods

To use the IBDesignable and IBInspectable attributes in Interface Builder while bringing JAMSVGImage in via cocoapods requires a bit of hackery:

  1. Make sure you're using Cocoapods 0.36.0.beta.1 or newer
  2. Add use_frameworks! at the top of your Podfile to enable Framework opt-in
  3. Add all SVGs have to a "Copy Files" build phase for the JAMSVGImage framework in your Pods project, like so:

Pods Example

Keep in mind that if you go this route, you will probably have to repeat these steps every time you run pod install.

An alternative to this workaround is to just drag the class files directly to your project (make sure you link to "libz.dylb").

Etc.

Why not use vector PDF with Xcode 6+ and iOS 7+? Xcode's vector PDF functionality is limited to rendering @1x, @2x, and @3x bitmaps at their natural size at build time. JAMSVGImage is far more versatile since SVGs are rendered at arbitrary size at runtime.

If you're using this in a production app, please let me know! I'd love to get feedback and figure out how to make it better. If there are any SVG parts you're missing out on you should fork, fix, and issue a pull request. The only supported SVG elements are "path" elements and associated styling information. JAMSVGImage passes all 19 of the SVG1.1 conformance tests for the "path" element.

jamsvgimage's People

Contributors

albertstartup avatar alexandrgraschenkov avatar baibaratsky avatar gilbert-jolly avatar jeehut avatar jmenter avatar keeshux avatar luosheng avatar m1entus avatar rwe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jamsvgimage's Issues

JAMSVG crashing for color gradients without "style" info.

I have a SVG Image that was generated by Photoshop that crashes JAMSVGImage:
https://gist.github.com/mark-whcc/1e28bd3420d0d21ac63d

The crash comes at line 78 of JAMStylizedBezierPath.m when it tries to add a color to an NSArray, but the color is nil.

It looks like there is a problem in JAMStylizedBezierPathFactory.m that would cause this, but this code is never hit. parseStyleColor: is scanning for stop-color: but my sample file has stop-color=. It will have the same problem with stop-opacity:.

The actual problem is parseStyleColor: is being called with no "style" (Line 89 of JAMStylizedBezierPathFactory.m) key in the dictionary, so the color, which is in the file, is not being found. This leaves the color property of JAMSVGGradientColorStop nil.

NSArray error

reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
screen shot 2015-01-05 at 4 51 07 pm

Possible values for transform attribute

Hello,

I stumbled upon an SVG file using "translate()" in transform attribute and noticed this library only handles "matrix()" values.

https://github.com/jmenter/JAMSVGImage/blob/master/Classes/JAMSVGImage/JAMStyledBezierPathFactory.m#L135

Support should be trivial as all matrices are just quick templates based on the generic matrix().

http://www.w3.org/TR/SVG/coords.html#TransformAttribute

I also wish I had the time to refactor JAMStyledBezierPathFactory a little bit for extensibility because I'm afraid the styledPathWithBezierPath:.. method might insanely grow.

Cheers

[JAMSVGImage containsPoint:] does not account for changed size.

If you have a large SVG (say, 512x512) and a small JAMSVGImageView (say, 32x32), although the image will render correctly, hit tests with [JAMSVGImageView pointInside: withEvent:] will incorrectly fail due to [JAMSVGImage containsPoint:] testing against the original path dimensions rather than the actually rendered ones.

Buttons cause xcode to hang

Looks like when trying to use the button, it will cause Xcode to hang. This was reproducible for me in the demo project as well.

I come from china

I operate in the inside of the Xib when the compiler can perform wrong but I would like to ask how to solve the two error.

error: IB Designables: Failed to update auto layout status: Failed to load designables from path (null)
error: IB Designables: Failed to render instance of JAMSVGButton: Failed to load designables from path (null)

JAMSVGImage size/viewBox calculation is incorrect.

While researching the correct fix for #18 , I read through a helpful description of how SVG handles the viewBox attribute here: http://tutorials.jenkov.com/svg/svg-viewport-view-box.html

viewBox defines an internal coordinate system which gets transformed into the parent coordinate system by a combination of width, height, and preserveAspectRatio properties.

JAVSVGParser currently ignores the SVG width and height attributes entirely, which makes the viewBox attribute meaningless when it is not equally sized to width and height. Currently viewBox origin is respected, but its size relative to the SVG width and height is not.

I believe the correct-ish behaviour is, in the SVG handling of JAMSVGParser:

  • Read width and height
  • Read preserveAspectRatio
  • Read viewBox
  • Image size is determined exclusively by width and height.
  • Path transformation is determined by combination of all of those attributes.

Caching should return copies of JAMSVGImage, not shared instances.

#17 implemented basic caching support for JAMSVGImage imageNamed:. However, rather than return copies of the cached image (which still has the primary benefit of skipping redundant SVG parsing and I/O), it returns a shared object with mutable properties.

Currently the only mutable property is scale, though if #20 is addressed, more properties could be usefully mutated.

This can cause unexpected problems and differs from expected behavior in which caches either return totally immutable shared objects or mutable copies of the original source.

Too thin lines in some SVG images

I'm using this framework since a while and recently some of my SVG images started rendering incorrectly. Specifically lines drawn within SVG images which had been say 5 pixels in width are now 1 pixel in width only. I could track the issue down to the changes made within this pull request: #27

Maybe @AlexandrGraschenkov knows what the issue could be? Something near adding the stroke in JAMStyledBezierPath.m perhaps?

How to cache JAMSVGImage into disk

this issue has troubled me for some time。i hava to store svg because such svg resource are loaded form netWork,but i find that if i archiver svg into data,read data from disk transform to svg,it cost some time to render svg。so i change other method ,i want to archiver JAMSVGImage instance ,but what i stuck in is that i can't find any way to archiver JAMSVGImage。now i just cache JAMSVGImage into memory with singleton,but as all wo know,every time when the app has kiiled or stop running background ,we lost the cache data in singleton,so i need you help to slove this issus,thanks!

[JAMSVGImage styledPaths] and JAMStyledBezierPath instances should probably be public.

These are extremely useful for being able to change the coloring of assets, for example, by looping through the paths and setting fillColor.

If these are mutable, however, it should be considered that it may be useful for JAMSVGImage to observe the properties of those subpaths in order to trigger setNeedsDisplay() when changed. Currently I expose these properties with a category and am careful to call setNeedsDisplay() manually.

Cocoapods not up to date?

Is there a reason why when I download the current cocoapods, it does not have the latest codebase? I had to fork in order to get the latest one b/c the when I do pod install 'JAMSVGImage', the code to set the line width in the bezier path is missing which messes up my SVGs. For now I have forked it in order to work.

[JAMSVGImageView pointInside: withEvent:] unexpectedly applies only to interior paths.

This differs unexpectedly from the behavior of UIImageView which, when userInteractionEnabled is true, detects hits on the entire frame regardless of transparent pixels. The default behaviour makes e.g. custom buttons tappable in their entire frame as expected.

Being able to detect hits on paths is certainly useful, however, so it might be better to have this as a separate flag (e.g. passThroughEventsOnTransparentRegions or userInteractionExcludesTransparent or something) that defaults to false.

Set attributes for SVG

Dears,

How could I define the attributes for the SVG, if I want to use the fillColor and Stroke with below code, any example or hint please?

    JAMSVGImage *tiger = [JAMSVGImage imageNamed:@"tiger"];
    JAMSVGImageView *tigerImageView = [JAMSVGImageView.alloc initWithSVGImage:tiger];

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.