开发者

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

开发者 https://www.devze.com 2023-01-12 22:42 出处:网络
Is it possible to create a CGPath开发者_JS百科 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:

Is it possible to create a CGPath开发者_JS百科 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


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.


[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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号