编辑 SVG 文件 – C# 示例

Aspose.SVG for .NET 允许您编辑 SVG 文件并更改其内容。 API 的文档对象模型 (DOM) 与官方 SVG 规范 完全兼容,意味着可以完全控制 SVG 节点及其字段进行编辑。您可以通过附加新节点、删除或编辑现有节点的内容来修改文档。

在本文中,我们将展示如何使用 Aspose.SVG for .NET 库编辑 SVG,并考虑如何向 SVG 文档添加元素并编辑它们的详细 C# 示例。

将元素添加到 SVG 文档

Aspose.SVG for .NET API 允许您向文档添加各种元素。首先,您将创建一个新元素或节点;然后,您可以将元素添加到文档中。

  1. 您可以使用 SVGDocument 类的 CreateElementNS(namespaceURI, QualifiedName) 方法创建 Element 类的实例 – 给定限定的所需元素名称和命名空间 URI。 namespaceURI 设置对 W3C SVG 规范的引用。 qualifiedName 必须包含元素的字符串标签名称。请记住,您必须使用类型转换(显式转换)来获取相应的元素。

  2. 要向 SVG 文档添加元素,API 提供了 Node 类的 InsertBefore(node, child) 方法,该方法在现有子节点之前插入 node 或如果“child”为空,则位于子级列表的末尾。

SVGDocument 类的 RootElement 属性指向文档的根 <svg> 元素。以下代码片段说明了如何创建 <g> 元素并将其添加为 SVG 文档中的第一个子元素。

1    var svgElement = document.RootElement;
2    var gElement = (SVGGElement)document.CreateElementNS("https://www.w3.org/2000/svg", "g");
3    svgElement.InsertBefore(gElement, svgElement.FirstChild);

我们可以使用 Element 类的 SetAttribute(name, value)GetAttribute(name)HasAttribute(name)RemoveAttribute(name) 方法来指定元素属性及其值。

例如,如果您创建一组图形元素并将它们放入<g>元素中,则可以设置公共参数:

1    gElement.SetAttribute("fill", "#8A8D8F");
2    gElement.SetAttribute("stroke", "magenta");
3    gElement.SetAttribute("stroke-width", "4");

如何将基本形状添加到 SVG 文档

可以使用 CreateElementNS(namespaceURI, QualifiedName) 方法创建基本的 SVG 形状。 qualifiedName 必须包含 SVG 图形元素的字符串标记名称。

这样你就可以创建SVG圆形(SVGCircleElement class, qualifiedName = “circle”),椭圆(SVGEllipseElement class, qualifiedName = “ellipse”),矩形(SVGRectElement class, qualifiedName = “rect”),线条(SVGLineElement class, qualifiedName = “line”)、折线(SVGPolylineElement 类,qualifiedName = “polyline”)、多边形(SVGPolygonElement class, qualifiedName = “polygon”)和贝塞尔曲线(SVGPathElement class, qualifiedName = “path”)。

SVG 圆

每个图形元素都有自己特定的属性(property),通过这些属性可以控制其参数和特性。 Cx, Cy, RSVGAnimatedLength 类型的圆属性,可以通过构造 element.X.BaseVal.Value 来设置或读取其静态数据。

以下代码片段显示了如何创建 SVG 圆圈并将其添加到现有 SVG 文件的 <svg> 元素中:

 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Dom;
 4using Aspose.Svg.Paths;
 5...
 6
 7    // Set SVG Namespace Url
 8    string SvgNamespace = "https://www.w3.org/2000/svg";
 9
10    string documentPath = Path.Combine(DataDir, "basic-shapes.svg");
11
12    using (var document = new SVGDocument(documentPath))
13    {
14        // Get root <svg> element of the document
15        var svgElement = document.RootElement;
16
17        // Create a <circle> element and set attributes values
18        var circleElement = (SVGCircleElement)document.CreateElementNS(SvgNamespace, "circle");
19        circleElement.Cx.BaseVal.Value = 100F;
20        circleElement.Cy.BaseVal.Value = 100F;
21        circleElement.R.BaseVal.Value = 50F;
22        circleElement.SetAttribute("fill", "Salmon");
23
24        // Add the <circle> element as the first child to <svg> element
25        svgElement.InsertBefore(circleElement, svgElement.FirstChild);
26
27    	// Work with the document here...
28    	// Add a polyline and change stroke attributes for all circle and ellipse elements (see later)
29    }
30    // Save the document
31    document.Save(Path.Combine(OutputDir, "basic-shapes_out.svg"));

椭圆 (Cx, Cy, Rx, Ry),矩形 (X, Y, Width, Height, Rx, Ry) 和直线 (X1, Y1, X2, Y2) 都有自己的属性可以类似地设置。

SVG 折线 – SVG Polyline

SVGPolygonElementSVGPolylineElement 具有 SVGPointList 类型的 Points 属性,该属性提供对 points 属性基本内容的访问,该属性唯一匹配 SVG 语法。

以下代码片段说明了创建 SVG 折线的简单示例:

 1    // Set SVG Namespace Url
 2    string SvgNamespace = "https://www.w3.org/2000/svg";
 3
 4    // Create a <polyline> element and set attributes values:
 5	var polylineElement = (SVGPolylineElement)document.CreateElementNS(SvgNamespace, "polyline");
 6    SVGPoint point1 = svgElement.CreateSVGPoint();
 7    point1.X = 270;
 8    point1.Y = 240;
 9    SVGPoint point2 = svgElement.CreateSVGPoint();
10    point2.X = 290;
11    point2.Y = 220;
12    SVGPoint point3 = svgElement.CreateSVGPoint();
13    point3.X = 310;
14    point3.Y = 240;
15    polylineElement.Points.AppendItem(point1);
16    polylineElement.Points.AppendItem(point2);
17    polylineElement.Points.AppendItem(point3);
18    polylineElement.SetAttribute("stroke", "grey");
19    polylineElement.SetAttribute("stroke-width", "5");
20    polylineElement.SetAttribute("fill", "none");
21
22	// Add the SVG polyline to children of the <svg> element
23	svgElement.AppendChild(polylineElement);

CreateSVGPoint() 方法生成 SVGPoint 类的实例,您可以在其中通过同名属性设置 XY 值。默认对象被初始化为自定义坐标系中的点 (0,0)。

AppendItem(T newItem) 方法在列表末尾插入一个新点。直线连接列表中的这些点并形成折线或多边形 – 由闭合折线形成的平面几何形状。

AppendChild(node) 方法将新子节点添加到该节点的子节点列表的末尾。代码片段显示,指定了 strokestroke-widthfill 属性,并且 polylineElement 作为最后一个子元素插入到 <svg> 元素中。

考虑编辑现有 SVG 文件 basic-shapes.svg 的示例:我们将添加上述圆形和折线,并更改所有圆形和椭圆形的笔划属性。以下代码片段显示了如何查找 <svg> 元素中的所有圆形和椭圆形并替换它们的描边属性:

1    // Set stroke attributes for all <circle> and <ellipse> elements
2    foreach (Element element in svgElement.Children)
3    {
4        if (element is SVGCircleElement || element is SVGEllipseElement)
5        {
6            element.SetAttribute("stroke-width", "6");
7            element.SetAttribute("stroke", "#C8102E");
8        }
9    }

该图显示了原始 SVG 文件 basic-shapes.svg 和编辑(修改)的文件的可视化。

文本“原始 svg 图像和编辑后的 ​​svg 图像”

编辑 SVG 路径 – Edit SVG Path

要使用 Aspose.SVG API 创建 SVG 路径,您需要使用 CreateElementNS(namespaceURI, QualifiedName) 方法创建 SVGPathElement 类的实例。

方法 CreateSVGPathSegMovetoAbs(x, y)CreateSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1)CreateSVGPathSegCurvetoQuadraticSmoothAbs(x, y) 采用以下参数路径数据命令“M、C”和“T”作为它们自己的参数。 SVGPathSegList 类型的 PathSegList 属性提供对 d 属性内容的访问,以路径段列表的形式,与 SVG 语法匹配(详细信息请参阅文章 SVG Path Data)。

以下代码片段显示了如何创建 SVG 路径并将其添加到 <svg> 元素中:

 1    // Create a <path> element
 2    var pathElement = (SVGPathElement)document.CreateElementNS(SvgNamespace, "path");
 3
 4	// Set d attribute parameters – SVG path data
 5	SVGPathSeg pathSeg1 = pathElement.CreateSVGPathSegMovetoAbs(10, 200);
 6	SVGPathSeg pathSeg2 = pathElement.CreateSVGPathSegCurvetoQuadraticAbs(180, 200, 25, 210);
 7	SVGPathSeg pathSeg3 = pathElement.CreateSVGPathSegCurvetoQuadraticSmoothAbs(300, 250);
 8	SVGPathSeg pathSeg4 = pathElement.CreateSVGPathSegCurvetoQuadraticSmoothAbs(420, 250);
 9	SVGPathSeg pathSeg5 = pathElement.CreateSVGPathSegCurvetoQuadraticSmoothAbs(490, 150);
10	pathElement.PathSegList.AppendItem(pathSeg1);
11	pathElement.PathSegList.AppendItem(pathSeg2);
12	pathElement.PathSegList.AppendItem(pathSeg3);
13	pathElement.PathSegList.AppendItem(pathSeg4);
14	pathElement.PathSegList.AppendItem(pathSeg5);
15
16	// Set fill and stroke attributes
17	pathElement.SetAttribute("stroke", "magenta");
18	pathElement.SetAttribute("fill", "none");
19	pathElement.SetAttribute("stroke-width", "4");
20
21	// Add the path as the first child in the <svg> element
22	svgElement.InsertBefore(pathElement, svgElement.FirstChild);

您可以在 DOM、编程、文档处理和文件导航方面使用此类详细且完整的代码。使用 SetAttribute() 方法,您可以在一行上编写 SVG 路径数据 d 设置的代码。

在下面的示例中,我们使用一行代码创建相同的路径(原始 SVG 路径)。此外,我们将在原始路径中编辑 moveto(x,y) MT(x,y) 命令的参数以接收新路径。

 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Paths;
 4...
 5
 6    // Set SVG Namespace Url
 7    string SvgNamespace = "https://www.w3.org/2000/svg";
 8
 9    using (var document = new SVGDocument())
10    {
11        var svgElement = document.RootElement;
12
13        // Create a <path> element and set SVG path data 
14        var pathElement = (SVGPathElement)document.CreateElementNS(SvgNamespace, "path");
15        pathElement.SetAttribute("d", "M 10 200 Q 25 110 180 200 T 300 250 T 420 250 T 490 150");
16        
17        // Edit SVG path
18        foreach (SVGPathSeg pathSeg in pathElement.PathSegList)
19        {
20            // Editing T commands parameters
21            if (pathSeg is SVGPathSegCurvetoQuadraticSmoothAbs)
22            {
23                SVGPathSegCurvetoQuadraticSmoothAbs pathSegCurvetoQuadraticSmoothAbs = pathSeg as SVGPathSegCurvetoQuadraticSmoothAbs;
24                pathSegCurvetoQuadraticSmoothAbs.X -= 60;
25                pathSegCurvetoQuadraticSmoothAbs.Y -= 65;
26            }
27            //  Editing M command parameters
28            if (pathSeg is SVGPathSegMovetoAbs)
29            {
30                SVGPathSegMovetoAbs pathSegMovetoAbs = pathSeg as SVGPathSegMovetoAbs;
31                pathSegMovetoAbs.X = 200;
32                pathSegMovetoAbs.Y = 100;
33            }
34        }
35        // Set fill and stroke attributes
36        pathElement.SetAttribute("stroke", "red");
37        pathElement.SetAttribute("fill", "none");
38        pathElement.SetAttribute("stroke-width", "4");
39
40        // Add the <path> element as the first child to the <svg> element
41    	svgElement.InsertBefore(pathElement, svgElement.FirstChild);
42
43    	// Save the document
44        document.Save(Path.Combine(OutputDir, "edit-svg-path-data.svg"));
45    }

该图展示了原始路径(黑色)和修改后的路径(红色)。您可以通过链接 – edit-svg-path-data.svg 查看并保存编辑后的 ​​SVG 文件。

文本“原始路径和编辑路径”

要编辑 SVG 文件,您必须首先在文档中找到要编辑的元素。有多种方法可以做到这一点,例如 CSS 选择器或 XPath 查询。有关如何使用文档导航来编辑 SVG 文件的详细信息,请参阅 Navigation & Inspection SVG 文章。

如果您想更改元素的 SVG 颜色,请参阅 如何更改 SVG 颜色 文章中的详细信息。在这里,您将学习如何使用 Aspose.SVG for .NET 库处理 SVG 颜色,并考虑如何更改元素的 SVG 颜色或更改 SVG 文件中的背景颜色。

在现有位图上绘制 SVG

位图可以用作绘图的背景。您可以附加 SVG 形状、路径或文本。例如,下图是在位图上添加圆圈和文字作为背景而成的:

1<svg xmlns="http://www.w3.org/2000/svg">
2	<image href="http://docs.aspose.com/svg/images/api/seaside.jpg" height="480" width="640" x="20" y="20"/>
3	<text style="font-size: 1.4em;" x="420px" fill="gold" y="280px">The beach is beautiful...</text>
4	<circle cx="520" cy="120" r="60" stroke="gold" stroke-width="70" fill="none" stroke-dasharray="2,14"/>
5</svg>

以下 C# 代码从头开始创建上面的 SVG 文档。我们向文档添加一些 SVG 元素,例如图像、文本和圆形元素,然后将 SVG 文档保存到文件中:

  1. 使用 SVGDocument 类创建 SVG 文档,并使用 RootElement 属性访问根 SVG 元素。
  2. 创建一个 <image> 元素,设置所需的属性,并将其添加到 <svg> 元素中。
  3. 以类似的方式,使用 SVGTextElement 类创建一个 <text> 元素并设置所需的属性。使用 Style 属性设置字体大小,使用 SetAttribute(name, value) 方法指定 x、yfill 等属性。
  4. 使用 SVGCircleElement 类创建一个 <circle> 元素。 cx、cyr 属性定义圆的中心坐标和半径。其他属性,如stroke, stroke-width, fillstroke-dasharray,用于设置圆形的样式。
  5. 使用 AppendChild() 方法将创建的 SVG 元素(imageElement、textElement 和 CircleElement)添加到 SVG 根元素 (svgElement) 的子元素列表的末尾。
  6. 调用 Save() 方法将 SVG 文档保存到指定输出目录中命名的文件中。
 1using Aspose.Svg;
 2using System.IO;
 3...
 4    // Set SVG Namespace Url
 5    string SvgNamespace = "http://www.w3.org/2000/svg";
 6
 7    using (var document = new SVGDocument())
 8    {
 9        var svgElement = document.RootElement;
10
11        // Create an <image> element and add it into svgElement
12        var imageElement = (SVGImageElement)document.CreateElementNS(SvgNamespace, "image");
13        imageElement.Href.BaseVal = "http://docs.aspose.com/svg/images/api/seaside.jpg";
14        imageElement.Height.BaseVal.Value = 480;
15        imageElement.Width.BaseVal.Value = 640;
16        imageElement.X.BaseVal.Value = 20;
17        imageElement.Y.BaseVal.Value = 20;
18        svgElement.AppendChild(imageElement);
19
20        // Create a <text> element, set its attributes, and it into svgElement
21        var textElement = (SVGTextElement)document.CreateElementNS(SvgNamespace, "text");
22        textElement.Style.FontSize = "1.4em";
23        textElement.SetAttribute("x", "420px");
24        textElement.SetAttribute("fill", "gold");
25        textElement.SetAttribute("y", "280px");
26        textElement.TextContent = "The beach is beautiful...";
27        svgElement.AppendChild(textElement);
28
29        // Create a <circle> element, set its attributes, and add it into svgElement
30        var circleElement = (SVGCircleElement)document.CreateElementNS(SvgNamespace, "circle");
31        circleElement.Cx.BaseVal.Value = 520;
32        circleElement.Cy.BaseVal.Value = 120;
33        circleElement.R.BaseVal.Value = 60;
34        circleElement.SetAttribute("stroke", "gold");
35        circleElement.SetAttribute("stroke-width", "70");
36        circleElement.SetAttribute("fill", "none");
37        circleElement.SetAttribute("stroke-dasharray", "2,14");
38        svgElement.AppendChild(circleElement);
39
40        // Save the document
41        document.Save(Path.Combine(OutputDir, "svg-drawing-on-bitmap.svg"));
42    }

我们使用较大的“笔画宽度”值绘制了 SVG 圆。应用 stroke-dasharray 属性将圆的笔划转换为虚线。通过选择填充未填充区域的值,可以达到所需的视觉效果。有关样式属性属性的更多信息,请参阅文章 SVG 中的填充和描边

文本“添加了 SVG 文本和 SVG 圆圈的图像”

您可以从 GitHub 下载完整的示例和数据文件。关于从 GitHub 下载并运行示例,您可以从 如何运行示例 部分找到。

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.