将BezierPath转换为SVG文件 [英] Turn a BezierPath into an SVG file

查看:89
本文介绍了将BezierPath转换为SVG文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从下面的代码生成的NSBezierPath,我想将此路径转换为一个可以导入Adobe Illustrator的svg文件(请参阅下面的svg代码).任何想法如何做到这一点?

I have a NSBezierPath produced from code below, and I want to turn this path into a svg file (see the svg code below) that I can import into Adobe Illustrator. Any ideas how to do this?

BezierPath描述

BezierPath description

NSColor* color0 = [NSColor colorWithCalibratedRed: 0 green: 0 blue: 0 alpha: 1];

{
    //// Bezier Drawing
    NSBezierPath* bezierPath = [NSBezierPath bezierPath];
    [bezierPath moveToPoint: NSMakePoint(2, 30.41)];
    [bezierPath curveToPoint: NSMakePoint(8.41, 1.91) controlPoint1: NSMakePoint(5.73, 41.21) controlPoint2: NSMakePoint(17.37, 63.33)];
    [bezierPath curveToPoint: NSMakePoint(49.79, 1.53) controlPoint1: NSMakePoint(45.32, 94.95) controlPoint2: NSMakePoint(41.89, 1.26)];
    [bezierPath setMiterLimit: 4];
    [bezierPath setLineCapStyle: NSRoundLineCapStyle];
    [bezierPath setLineJoinStyle: NSRoundLineJoinStyle];
    [color0 setStroke];
    [bezierPath setLineWidth: 3];
    [bezierPath stroke];
}

svg说明

svg description

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="200px" height="200px" viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve">
<g id="n1">
    <path fill="none" stroke="#000000" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" d="M2,169.585
        c3.73-10.794,15.369-32.913,6.406,28.508c36.91-93.04,33.489,0.644,41.384,0.381"/>
</g>
</svg>

一些观察

BezierPath使用[NSBezierPath bezierPath]来指示路径数据的开始,而svg使用d =路径数据".

BezierPath uses [NSBezierPath bezierPath] to indicate start of path data while svg use d = "path data".

BezierPath使用moveToPoint,而svg使用M.

BezierPath uses moveToPoint while svg uses M.

BezierPath使用curveToPoint,而svg使用c.

BezierPath uses curveToPoint while svg uses c.

svg不使用空格,而是使用非常紧凑的形式.

svg does not use spaces, but instead uses a very compact form.

BezierPath使用绝对坐标,而svg使用相对坐标.

BezierPath uses absolute coordinates while svg uses relative coordinates.

对于曲线,BezierPath使用顺序为"point,controlPoint1,controlPoint2",而svg使用顺序为"controlPoint1,controlPoint2,point".

For curves BezierPath uses the order "point, controlPoint1, controlPoint2" while svg uses the order "controlPoint1, controlPoint2, point".

请注意,我们将路径嵌入到svg中width ="200px" height ="200px"的框中.

Observe that we are embedding the path into a box of width="200px" height="200px" in svg.

使用这些观察结果,我们可以将BezierPath描述转换为svg描述,如下所示:

Using these observations we could translate BezierPath description into svg description as follows:

  1. moveToPoint:NSMakePoint(2,30.41)]

转换为M2,169.59(M = MoveToPoint,2 = 2,200-30.41 = 169.59)

is translated into M2,169.59 (M=MoveToPoint, 2=2, 200-30.41=169.59)

  1. curveToPoint:NSMakePoint(8.41,1.91)controlPoint1:NSMakePoint(5.73,41.21)controlPoint2:NSMakePoint(17.37,63.33)]

被翻译成

c3.73-10.794,15.369-32.913,6.406,28.508

c3.73-10.794,15.369-32.913,6.406,28.508

(c = curveToPoint,3.73 = 5.73-2,-10.8 = 30.41-41.21,15.37 = 17.37-2,32.89 = 63.3-30.41,6.41 = 8.41-2,28.5 = 30.41-1.91))

(c=curveToPoint, 3.73=5.73-2, -10.8=30.41-41.21, 15.37=17.37-2, 32.89=63.3-30.41, 6.41=8.41-2, 28.5=30.41-1.91))

以此类推

我想我可以使用这些观察来进行自己的翻译,但是如果已经可以使用我编写的代码,那就更好了,更笼统了.

I guess I could use these observations to make my own translations, but it would be nicer and more general if there was already written code that I could use.

推荐答案

这是解决我的问题的一种解决方案.但这仅适用于贝塞尔曲线路径.观察到我仅填写路径数据.这之前必须带有一些下面类型的静态文本.如果有人有一个更通用或更完善的解决方案,我想听听.

Here is one solution that solves my problem. But it only works for Bezier paths. Observe that I am only filling out the path data. This has to be preceded with some static text of type below. If anybody has a more general or nicer solution, I would like to hear it.

<?xml version="1.0" encoding="utf-8"?>
 ...
stroke-linejoin="round

还可以观察到我使用的是200x200的画布(翻转y坐标时为200).

Observe also that I am using a canvas which is 200x200 (hence 200 when flipping y coordinates).

-(NSString *)svgFromBezierPath:(NSBezierPath *)path {
    int numElements = (int) [path elementCount];
    if (numElements == 0) {
        return nil;
    }

    NSString *result = @"d=\"";
    NSPoint points[3];
    NSString *xStr;
    NSString *yStr;
    NSString *xCp1;
    NSString *yCp1;
    NSString *xCp2;
    NSString *yCp2;
    NSString *temp;
    double yValue;

    for (int i=0; i < numElements; i++)
    {
        switch ([path elementAtIndex:i associatedPoints:points])
        {
            case NSMoveToBezierPathElement:
                xStr = [NSString stringWithFormat:@"%0.2f", points[0].x];
                yValue = 200 - points[0].y;
                yStr = [NSString stringWithFormat:@"%0.2f", yValue];

                temp = [NSString stringWithFormat:@"M%@,%@,",xStr, yStr];
                result = [result stringByAppendingString:temp];
                break;

            case NSLineToBezierPathElement:
                xStr = [NSString stringWithFormat:@"%0.2f", points[0].x];
                yValue = 200 - points[0].y;
                yStr = [NSString stringWithFormat:@"%0.2f", yValue];

                temp = [NSString stringWithFormat:@"L%@,%@,",xStr, yStr];
                result = [result stringByAppendingString:temp];
                break;

            case NSCurveToBezierPathElement:
                xStr = [NSString stringWithFormat:@"%0.2f", points[0].x];
                yValue = 200 - points[0].y;
                yStr = [NSString stringWithFormat:@"%0.2f", yValue];

                xCp1 = [NSString stringWithFormat:@"%0.2f", points[1].x];
                yValue = 200 - points[1].y;
                yCp1= [NSString stringWithFormat:@"%0.2f", yValue];

                xCp2 = [NSString stringWithFormat:@"%0.2f", points[2].x];
                yValue = 200 - points[2].y;
                yCp2= [NSString stringWithFormat:@"%0.2f", yValue];

                temp = [NSString stringWithFormat:@"C%@,%@,%@,%@,%@,%@,", xStr, yStr, xCp1, yCp1,xCp2, yCp2];
                result = [result stringByAppendingString:temp];
                break;

            case NSClosePathBezierPathElement:
                result = [result stringByAppendingString:@"z,"];
                break;
        }
    }

    result = [result substringToIndex:result.length-1]; // delete the trailing comma
    result = [result stringByAppendingString:@"\"/></svg>"];
    return result;
}

这篇关于将BezierPath转换为SVG文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆