将 SVG 路径数据转换为 GDI+图形路径数据

发布于 2024-11-02 08:05:19 字数 121 浏览 0 评论 0原文

有没有一种简单的方法可以将 SVG 路径标记转换为 C# System.Drawing.Drawing2D.GraphicsPath?它们都是密切相关的,我希望能够轻松地将 SVG 路径数据转换为 GraphicsPath 点。

Is there an easy way to convert an SVG path tag into a C# System.Drawing.Drawing2D.GraphicsPath? They are both closely related and I was hoping there would be an easy to convert the SVG path data into GraphicsPath Points.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冬天的雪花 2024-11-09 08:05:19

此 SVG 项目通过以下方式提供了解决方案:

var pathData = ...;

var graphicsPath = new GraphicsPath();

foreach (var segment in SvgPathBuilder.Parse(pathData))
    segment.AddToPath(graphicsPath);

graphics.DrawPath(Pens.Black, graphicsPath);

它可以通过以下方式作为 NuGet 包提供:

PM> Install-Package Svg

This SVG project provides a solution in the following way:

var pathData = ...;

var graphicsPath = new GraphicsPath();

foreach (var segment in SvgPathBuilder.Parse(pathData))
    segment.AddToPath(graphicsPath);

graphics.DrawPath(Pens.Black, graphicsPath);

It's available as a NuGet package via:

PM> Install-Package Svg
许你一世情深 2024-11-09 08:05:19

虽然 SVG 路径和 GraphicsPath 看起来相似并且具有相同的用途,但没有简单的方法,但在指定和处理事物的方式上存在一些差异。一个示例:SVG 弧定义与 GraphicsPath 定义弧的方式不同,因此您需要执行一点三角函数来转换它。

另请查看在 .NET/C# 中绘制 SVG?

There's no easy way, although SVG paths and GraphicsPath look similar and serve the same purpose, there are some differences in how things are specified and handled. One example: SVG arc definition is different from how GraphicsPath defines arcs, so you'll need to do a little bit of trigonometry to convert it.

Also check out Drawing SVG in .NET/C#?

半山落雨半山空 2024-11-09 08:05:19

我希望这还不算晚!查看 AGG 的 svg 查看器程序的源代码: https://github.com/timothytylee /agg/tree/master/examples/svg_viewer

源代码采用 C++ 编写,使用 AGG 图形引擎,但很容易转换为 GDI+。它还处理 SVG Arc 到 Bezier Arc 的转换,然后可以与 GDI+ 一起使用。

祝你好运

I hope this ain't late! Check out the source code of the svg viewer program from AGG: https://github.com/timothytylee/agg/tree/master/examples/svg_viewer

The source code is in C++ and uses the AGG graphics engine, but it's easy to translate to GDI+. It also handles the conversion of SVG Arc to a Bezier Arc which can then be used with GDI+.

Good luck

假扮的天使 2024-11-09 08:05:19

事情没那么复杂。

如果 svg 路径仅包含 MLQZ ZM 函数,则您的方法如下所示:

private GraphicsPath svgMLQZToGraphicsPath(string svgString)
{
    GraphicsPath graphicsPath = new GraphicsPath();
    float[] x = new float[4];
    float[] y = new float[4];
    string prev = "";
    string[] splits = svgString.Split(' ');
    for (int s = 0; s < splits.Length; s++)
    {
        if (splits[s].Substring(0, 1) == "M")
        {
            x[0] = float.Parse(splits[s].Substring(1).Replace('.', ','));
            y[0] = float.Parse(splits[s + 1].Replace('.', ','));
            s++;
            prev = "M";
            graphicsPath.StartFigure();
        }
        else if (splits[s].Substring(0, 1) == "L")
        {
            x[1] = float.Parse(splits[s].Substring(1).Replace('.', ','));
            y[1] = float.Parse(splits[s + 1].Replace('.', ','));
            graphicsPath.AddLine(new PointF(x[0], y[0]), new PointF(x[1], y[1]));
            x[0] = x[1]; // x[1] = new float();
            y[0] = y[1]; //y[1] = new float();
            s++;
            prev = "L";
        }
        else if (splits[s].Substring(0, 1) == "Q")
        {
            x[1] = x[0] + (2 / 3) * (float.Parse(splits[s].Substring(1).Replace('.', ',')) - x[0]);
            y[1] = y[0] + (2 / 3) * (float.Parse(splits[s + 1].Replace('.', ',')) - y[0]);
            x[3] = float.Parse(splits[s + 2].Replace('.', ','));
            y[3] = float.Parse(splits[s + 3].Replace('.', ','));
            x[2] = x[3] + (2 / 3) * (float.Parse(splits[s].Substring(1).Replace('.', ',')) - y[3]);
            y[2] = y[3] + (2 / 3) * (float.Parse(splits[s + 1].Replace('.', ',')) - y[3]);
            graphicsPath.AddBezier(new PointF(x[0], y[0]), new PointF(x[1], y[1]), new PointF(x[2], y[2]), new PointF(x[3], y[3]));
            x[0] = x[3]; 
            y[0] = y[3]; 
            s = s + 3;
            prev = "Q";
        }
        else if (splits[s].Substring(0, 1) == "Z")
        {
            graphicsPath.CloseFigure();
            if (splits[s].Length >= 2 && splits[s].Substring(0, 2) == "ZM")
            {
                x[0] = float.Parse(splits[s].Substring(2).Replace('.', ','));
                y[0] = float.Parse(splits[s + 1].Replace('.', ','));
                s++;
                graphicsPath.StartFigure();
                prev = "M";
            }
        }
        else
        {
            string ok = @"^[a-zA-Z]*$";
            if (!Regex.IsMatch(splits[s + 1].Substring(0, 1), ok))
            {
                string replace = prev + splits[s + 1];
                splits[s + 1] = replace;
            }
        }
    }
    return graphicsPath;
}

It's not that complicated.

If the svg path only consists of M L Q Z ZM functions your method looks like this:

private GraphicsPath svgMLQZToGraphicsPath(string svgString)
{
    GraphicsPath graphicsPath = new GraphicsPath();
    float[] x = new float[4];
    float[] y = new float[4];
    string prev = "";
    string[] splits = svgString.Split(' ');
    for (int s = 0; s < splits.Length; s++)
    {
        if (splits[s].Substring(0, 1) == "M")
        {
            x[0] = float.Parse(splits[s].Substring(1).Replace('.', ','));
            y[0] = float.Parse(splits[s + 1].Replace('.', ','));
            s++;
            prev = "M";
            graphicsPath.StartFigure();
        }
        else if (splits[s].Substring(0, 1) == "L")
        {
            x[1] = float.Parse(splits[s].Substring(1).Replace('.', ','));
            y[1] = float.Parse(splits[s + 1].Replace('.', ','));
            graphicsPath.AddLine(new PointF(x[0], y[0]), new PointF(x[1], y[1]));
            x[0] = x[1]; // x[1] = new float();
            y[0] = y[1]; //y[1] = new float();
            s++;
            prev = "L";
        }
        else if (splits[s].Substring(0, 1) == "Q")
        {
            x[1] = x[0] + (2 / 3) * (float.Parse(splits[s].Substring(1).Replace('.', ',')) - x[0]);
            y[1] = y[0] + (2 / 3) * (float.Parse(splits[s + 1].Replace('.', ',')) - y[0]);
            x[3] = float.Parse(splits[s + 2].Replace('.', ','));
            y[3] = float.Parse(splits[s + 3].Replace('.', ','));
            x[2] = x[3] + (2 / 3) * (float.Parse(splits[s].Substring(1).Replace('.', ',')) - y[3]);
            y[2] = y[3] + (2 / 3) * (float.Parse(splits[s + 1].Replace('.', ',')) - y[3]);
            graphicsPath.AddBezier(new PointF(x[0], y[0]), new PointF(x[1], y[1]), new PointF(x[2], y[2]), new PointF(x[3], y[3]));
            x[0] = x[3]; 
            y[0] = y[3]; 
            s = s + 3;
            prev = "Q";
        }
        else if (splits[s].Substring(0, 1) == "Z")
        {
            graphicsPath.CloseFigure();
            if (splits[s].Length >= 2 && splits[s].Substring(0, 2) == "ZM")
            {
                x[0] = float.Parse(splits[s].Substring(2).Replace('.', ','));
                y[0] = float.Parse(splits[s + 1].Replace('.', ','));
                s++;
                graphicsPath.StartFigure();
                prev = "M";
            }
        }
        else
        {
            string ok = @"^[a-zA-Z]*$";
            if (!Regex.IsMatch(splits[s + 1].Substring(0, 1), ok))
            {
                string replace = prev + splits[s + 1];
                splits[s + 1] = replace;
            }
        }
    }
    return graphicsPath;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文