Edit SVG File – C# Examples
Aspose.SVG for .NET lets you edit SVG files and make changes to their content. The API’s Document Object Model (DOM) is fully compatible with the official SVG specifications and means full control over SVG nodes and their fields for editing. You can modify the document by appending new nodes, removing, or editing the content of existing nodes.
In this article, we show how to edit SVG using Aspose.SVG for .NET library and consider detailed C# examples of how to add elements to an SVG document and edit them.
Add Elements to an SVG Document
Aspose.SVG for .NET API allows you to add various elements to a document. First, you would create a new element or node; then, you can add the element to the document.
You can use the CreateElementNS(
namespaceURI, qualifiedName
) method of the SVGDocument class to create an instance of the Element class – the required element of the given qualified name and namespace URI. ThenamespaceURI
sets the reference to W3C SVG specification. ThequalifiedName
must contain the string tag name of the element. Remember, you must use casting the type (explicit conversion) to get the corresponding element.To add an element to the SVG document, API provides the InsertBefore(
node, child
) method of the Node class, which inserts thenode
before the existing child node or at the end of the list of children if thechild
is null.
The
RootElement property of the
SVGDocument class points to the root <svg>
element of the document. The following code snippet illustrates how to create and add <g>
element as the first child in the SVG document.
1 var svgElement = document.RootElement;
2 var gElement = (SVGGElement)document.CreateElementNS("http://www.w3.org/2000/svg", "g");
3 svgElement.InsertBefore(gElement, svgElement.FirstChild);
We can specify element attributes and their values using the
SetAttribute(name, value
),
GetAttribute(name
),
HasAttribute(name
),
RemoveAttribute(name
) methods of the
Element class. For example, if you create a group of graphic elements and put them into the <g>
element, you can set common parameters:
1 gElement.SetAttribute("fill", "#8A8D8F");
2 gElement.SetAttribute("stroke", "magenta");
3 gElement.SetAttribute("stroke-width", "4");
How to add Basic Shapes to an SVG Document
The basic SVG shapes can be created using the
CreateElementNS(namespaceURI, qualifiedName
) method. The qualifiedName
must contain the string tag name of the SVG graphic element.
This way you can create SVG circles (SVGCircleElement class, qualifiedName = “circle”), ellipses (SVGEllipseElement class, qualifiedName = “ellipse”), rectangles (SVGRectElement class, qualifiedName = “rect”), lines (SVGLineElement class, qualifiedName = “line”), polylines (SVGPolylineElement class, qualifiedName = “polyline”), polygons (SVGPolygonElement class, qualifiedName = “polygon”) and Bezier curves (SVGPathElement class, qualifiedName = “path”).
SVG Circle
Each graphic element has its own specific attributes (properties), through which you can control its parameters and characteristics.
Cx, Cy, R
are circle properties of the
SVGAnimatedLength type, the static data for which can be set or read through the construction: element.X.BaseVal.Value
.
The following code snippet shows how to create an SVG circle and add it into the <svg>
element of the existing SVG file:
1using Aspose.Svg;
2using System.IO;
3using Aspose.Svg.Dom;
4using Aspose.Svg.Paths;
5...
6
7 // Set SVG Namespace Url
8 string SvgNamespace = "http://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"));
The ellipse (Cx, Cy, Rx, Ry
), the rectangle (X, Y, Width, Height, Rx, Ry
) and the line (X1, Y1, X2, Y2
) have their own attributes that may be set similarly.
SVG Polyline
The
SVGPolygonElement and
SVGPolylineElement have the Points
property of the
SVGPointList type, which provides access to the basic content of the points
attribute, which uniquely matches the SVG syntax.
A simple example of SVG polyline creating is illustrated in the following code snippet:
1 // Set SVG Namespace Url
2 string SvgNamespace = "http://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);
The
CreateSVGPoint() method produces an instance of the
SVGPoint class, in which you can set the X
and Y
values through the same name properties. The default object is initialized to point (0,0) in the custom coordinate system.
The
AppendItem(T newItem
)method inserts a new point at the end of the list. Straight lines connect these points in the list and make a polyline or polygon – a plane geometric shape formed by a closed polyline.
The
AppendChild(node
) method adds the new child to the end of the list of children of this node. The code snippet shows that the stroke
, stroke-width
, and fill
attributes are specified, and the polylineElement
is inserted in the <svg>
element as the last child.
Consider an example of editing an existing SVG file basic-shapes.svg: we will add the circle and polyline described above and change the stroke properties for all circles and ellipses. The following code snippet shows how to find all circles and ellipses in an <svg>
element and replace their stroke properties:
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 }
The figure shows the visualization of the original SVG file basic-shapes.svg and the file that was edited (modified).
Edit SVG Path
To create an SVG path using the Aspose.SVG API, you need to create an instance of the
SVGPathElement class using the CreateElementNS(namespaceURI, qualifiedName
) method.
The methods
CreateSVGPathSegMovetoAbs(x, y
),
CreateSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1
) and
CreateSVGPathSegCurvetoQuadraticSmoothAbs(x, y
) take parameters of path data commands M, C
, and T
as their own parameters. The
PathSegList property of the SVGPathSegList type provides access to the content of d
attribute, in the form of path segments list, that matches the SVG syntax (details are in the article
SVG Path Data).
The following code snippet shows how to create the SVG path and add it into <svg>
element:
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);
You can use such itemised and thorough code in terms of the DOM, programming, working with the document, and navigating the file. Using the
SetAttribute() method, you can write the code on a single line for the SVG path data d
setting.
In the following example, we use the one-line code to create the same path (original SVG path). Moreover, we will edit the parameters of the moveto(x,y) M
and T
(x,y) commands in the original path to receiving a new one.
1using Aspose.Svg;
2using System.IO;
3using Aspose.Svg.Paths;
4...
5
6 // Set SVG Namespace Url
7 string SvgNamespace = "http://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 }
The figure illustrates the original (black) and modified (red) paths. You can view and save the edited SVG file by following the link – edit-svg-path-data.svg.
To edit SVG file, you must first find the elements to edit in the document. There are a number of ways to do this, such as CSS selectors or XPath queries. Detailed information on how to edit SVG file using a navigation through the document can be found in the Navigation & Inspection SVG article.
If you want to change SVG colors for elements, please see the details in the How to Change SVG Color article. Here you learn how to work with SVG color using Aspose.SVG for .NET library and consider how to change SVG color of elements or change background color in SVG files.
SVG Drawing on Existing Bitmap
The bitmap can be used as a background for drawing. You can append the SVG shapes, paths, or text. For example, the figure below is made with the help of adding circle and text to the bitmap acting as the background:
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>
The following C# code creates the SVG document above from scratch. We add to the document some SVG elements such as an image, text, and a circle element and then save the SVG document to a file:
- Create an SVG document using the SVGDocument class and accesses the root SVG element using the RootElement property.
- Create an
<image>
element, set the required attributes, and add it to the<svg>
element.- Use the
CreateElementNS(
namespaceURI, qualifiedName
) method of the SVGDocument class to create an instance of the SVGImageElement class. - Use properties of the
SVGAnimatedLength type, the static data for which can be set or read through the construction:
element.X.BaseVal.Value
: set thehref, height, width, x,
andy
attributes.
- Use the
CreateElementNS(
- In a similar way, create a
<text>
element using the SVGTextElement class and set required attributes. Use the Style property to set the font size, and the SetAttribute(name, value
) method to specify attributes likex, y
, andfill
. - Create a
<circle>
element using the SVGCircleElement class. Thecx, cy
, andr
attributes define the center coordinates and radius of the circle. Other attributes likestroke, stroke-width, fill
, andstroke-dasharray
are used to style the circle. - Use the AppendChild() method to add the created SVG elements (imageElement, textElement, and circleElement) to the end of the list of children of the SVG root element (svgElement).
- Call the Save() method to save the SVG document to a file named in the specified output directory.
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 }
We painted the SVG circle with a big value of stroke-width
. The stroke-dasharray
attribute applying converts the circle’s stroke into a dashed line. By selecting values of the filled-unfilled areas, you can achieve the desired visual effect. For more information on style attributes’ properties, please see the article
Fills and Strokes in SVG.
In the chapter SVG Builder—Advanced SVG Creation and Modification, you will find a guide to manipulating SVG effectively using the Aspose.SVG Builder API, covering aspects from creating basic elements to advanced techniques such as mixins and syntactic sugar.
You can download the complete examples and data files from GitHub. About downloading from GitHub and running examples, you find out from the How to Run the Examples section.