简体   繁体   中英

How to create a CGPath from a file — i.e. SVG

Is it possible to create a CGPath from a given file?

SVG would be preferred, but anything will work.

PocketSVG will turn an SVG file into a UIBezierPath from which you can get a CGPath:

PocketSVG *myBezier = [[PocketSVG alloc] initFromSVGFileNamed:@"BezierCurve1-iPad"];    
UIBezierPath *myPath = myBezier.bezier;
//myPath.CGPath <--- your CGPath

[Update: in the intervening years from when I first answered this question, I released a class to handle this under MIT license: SVGgh SVGPathGenerator . Look for:

+(CGPathRef) newCGPathFromSVGPath:(NSString*)anSVGPath whileApplyingTransform:(CGAffineTransform)aTransform

]

I'm looking at doing this today, and all the operands except the absolute and relative arc operands map very neatly to the path creation API of CGMutablePathRef. I was googling to find the mathematic voodoo needed to make the SVG definition of an arc compatible with CGPathAddArcToPoint when I came across this question. You just have to parse the d attribute of the SVG path element, which you can get via the NSXMLParser object and a delegate you provide.

If you can make use of GPL'd code, which I cannot, then the Webkit source has a file SVGPathParser.cpp which has some useful tidbits. The W3C has some useful implementation notes , and Gabe Lerner implemented it in JavaScript.

Seems like there is a more clever solution SVGKit :

SVGKit is a Cocoa framework for rendering SVG files as Core Animation layers. All shapes are represented by instances of the CAShapeLayer class, and are, by design, animatable. SVGKit is compatible with the latest Mac OS X and iOS SDK's.

I struggled with this one too, scouring the web for a solution. SVGKit seems like the closest solution i could find, but still didn't do the job. The problem I had was that it seemed to only support certain SVG files and I was unsuccessful at converting any of my files to a compatible format. I even wrote my own parser, but the results were also inconsistent.

I began to look into SVG specs more deeply and there seems to be a few inconsistencies in how each vector editing tool generated these files. Then I ended up looking into Adobe's FXG format, which is based on SVG. One thing I noticed immediately was that the commands in the Path data were all absolute and not relative. This (IMHO) by far made FXG superior to SVG.

I was able to convert this to a CGPath that actually worked perfect. My current needs only required converting the Path data for use as clipping paths, but it's totally possible to support the full FXG spec.

Here's a little AIR app I threw together for generating Core Graphics commands from the FXG path data, that demonstrates the potential. http://iksnae.com/fxgtool/

Hopefully it helps you too.

Yes. It is possible. I haven't done this, but because SVG uses paths itself , it seems that mapping an SVG path to a CGPath would be something possible/manageable. The question at that point becomes how motivated are you? I didn't see any Objective-C libraries that already do this in a cursory google search, but it may be out there. I did see a Java implementation , that you could probably port.

Considering the lack of obvious solutions on the web, I would guess this isn't a very common need for app devs. There's probably a better/easier way to solve the problem at hand. If all you want is to display an SVG image, you could just embed a webview and let WebKit render it for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM