Преобразование данных пути SVG в данные GDI+ GraphicsPath

есть ли простой способ преобразовать тег пути SVG в систему C#.Рисунок.Drawing2D.GraphicsPath? Они оба тесно связаны, и я надеялся, что будет легко преобразовать данные пути SVG в точки GraphicsPath.

4 ответов


этот проект 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

нет простого способа, хотя пути SVG и GraphicsPath похожи и служат той же цели, есть некоторые различия в том, как вещи определяются и обрабатываются. Один пример: определение дуги SVG отличается от how GraphicsPath определяет дуги, поэтому вам нужно будет сделать немного тригонометрии, чтобы преобразовать его.

также проверить рисование SVG в .NET / C#?


надеюсь, еще не поздно! Проверьте исходный код программы SVG viewer из AGG:http://www.antigrain.com/svg/index.html

исходный код на C++ и использует графический движок AGG, но его легко перевести на GDI+. Он также обрабатывает преобразование дуги SVG в дугу Безье, которая затем может использоваться с GDI+.

удачи


это не так сложно.

Если путь svg состоит только из M L Q Z 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;
}