Редактирование файла SVG – примеры C#

Aspose.SVG для .NET позволяет редактировать файлы SVG и вносить изменения в их содержимое. Объектная модель документа (DOM) API полностью совместима с официальными спецификациями SVG и означает полный контроль над узлами SVG. Вы можете изменить документ, добавляя новые узлы, удаляя или редактируя содержимое существующих узлов.

В этой статье мы покажем, как редактировать SVG с помощью библиотеки Aspose.SVG for .NET, а также рассмотрим подробные примеры C# того, как добавлять элементы в документ SVG и редактировать их.

Добавьте элементы в документ SVG

Aspose.SVG для .NET API позволяет добавлять в документ различные элементы. Сначала вы создадите новый элемент или узел; затем вы можете добавить элемент в документ.

  1. Вы можете использовать метод CreateElementNS(namespaceURI,qualifiedName) класса SVGDocument для создания экземпляра класса Element – требуемого элемента с заданным полным именем и URI пространства имен. namespaceURI устанавливает ссылку на спецификацию W3C SVG. qualifiedName должно содержать имя строкового тега элемента.

  2. Чтобы добавить элемент в документ SVG, API предоставляет метод InsertBefore(node, child) класса Node, который вставляет node перед существующим дочерним узлом или в конце списка дочерних элементов, если «дочерний элемент» равен нулю.

Свойство RootElement класса SVGDocument указывает на корневой элемент <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);

Мы можем указать атрибуты элемента и их значения, используя SetAttribute(name, value), GetAttribute(name), HasAttribute(name), RemoveAttribute(name) методы класса Element.

Например, если вы создаёте группу графических элементов и помещаете их в элемент <g>, вы можете задать общие параметры:

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

Как добавить базовые фигуры в документ SVG

Базовые фигуры SVG можно создать с помощью метода CreateElementNS(namespaceURI,qualName). qualifiedName должно содержать имя строкового тега графического элемента SVG.

Таким образом вы можете создавать круги SVG (SVGCircleElement class, qualifiedName = “circle”), эллипсы (SVGEllipseElement class, qualifiedName = “ellipse”), кривые Безье (SVGPathElement class, qualifiedName = “path”) и так далее.

SVG круг – SVG Circle

Каждый графический элемент имеет свои определенные атрибуты (свойства), с помощью которых можно управлять его параметрами и характеристиками. Cx, Cy, R – свойства круга типа SVGAnimatedLength, статические данные для которого можно задать или прочитать через конструкцию: 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

SVGPolygonElement и SVGPolylineElement имеют свойство Points типа SVGPointList, которое обеспечивает доступ к базовому содержимому атрибута 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, в котором вы можете установить значения X и Y через свойства с тем же именем. Объект по умолчанию инициализируется точкой (0,0) в пользовательской системе координат.

Метод AppendItem(T newItem) вставляет новую точку в конец списка. Прямые линии соединяют эти точки в списке и образуют ломаную линию или многоугольник – плоскую геометрическую фигуру, образованную замкнутой полилинией.

Метод AppendChild(node) добавляет нового дочернего элемента в конец списка дочерних элементов этого узла. Фрагмент кода показывает, что атрибуты stroke, stroke-width и fill указаны, а 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 и файла, который был отредактирован (модифицирован).

Text «Исходное изображение svg и отредактированное изображение svg»

Редактировать путь SVG – Edit SVG Path

Чтобы создать путь SVG с помощью API Aspose.SVG, вам необходимо создать экземпляр класса SVGPathElement с помощью метода CreateElementNS(namespaceURI,qualName).

Методы CreateSVGPathSegMovetoAbs(x, y), CreateSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1) и CreateSVGPathSegCurvetoQuadraticSmoothAbs(x, y) принимают параметры команды данных пути M, C и T в качестве собственных параметров. Свойство PathSegList типа SVGPathSegList обеспечивает доступ к содержимому атрибута 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(), вы можете написать код в одной строке для настройки d данных пути SVG.

В следующем примере мы используем однострочный код для создания того же пути (исходный путь SVG). Более того, мы отредактируем параметры команд moveto(x,y) M и T(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    }

На рисунке показаны исходный (черный) и измененный (красный) пути. Посмотреть и сохранить отредактированный SVG-файл можно, пройдя по ссылке – edit-svg-path-data.svg.

Text «Исходные и отредактированные пути»

Чтобы отредактировать файл SVG, сначала необходимо найти в документе элементы для редактирования. Есть несколько способов сделать это, например, с помощью селекторов CSS или запросов XPath. Подробную информацию о том, как редактировать SVG-файл с помощью навигации по документу, можно найти в статье Навигация и проверка SVG.

Если вы хотите изменить цвета SVG для элементов, см. подробности в статье Как изменить цвет SVG. Здесь вы узнаете, как работать с цветом SVG с помощью библиотеки Aspose.SVG для .NET, а также узнаете, как изменить цвет элементов 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. Создайте документ SVG, используя класс SVGDocument, и получите доступ к корневому элементу SVG, используя свойство RootElement.
  2. Создайте элемент <image>, установите необходимые атрибуты и добавьте его к элементу <svg>.
    • Используйте метод CreateElementNS(namespaceURI,qualName) класса SVGDocument, чтобы создать экземпляр класса SVGImageElement.
    • Используйте свойства типа SVGAnimatedLength, статические данные для которых можно задать или прочитать через конструкцию: element.X.BaseVal.Value: задайте атрибуты href, height, width, x, и y.
  3. Аналогичным образом создайте элемент <text>, используя класс SVGTextElement и установите необходимые атрибуты. Используйте свойство Style для установки размера шрифта и метод SetAttribute(name, value) для указания таких атрибутов, как x, y и fill.
  4. Создайте элемент <circle>, используя класс SVGCircleElement. Атрибуты cx, cy и r определяют координаты центра и радиус круга. Другие атрибуты, такие как stroke, stroke-width, fill и stroke-dasharray, используются для стилизации круга.
  5. С помощью метода AppendChild() добавьте созданные элементы SVG (imageElement, textElement и CircleElement) в конец списка дочерних элементов корневого элемента SVG (svgElement).
  6. Вызовите метод Save(), чтобы сохранить документ SVG в файл с именем в указанном выходном каталоге.
 1using Aspose.Svg;
 2using System.IO;
 3...
 4
 5    // Set SVG Namespace Url
 6    string SvgNamespace = "http://www.w3.org/2000/svg";
 7
 8    using (var document = new SVGDocument())
 9    {
10        var svgElement = document.RootElement;
11
12        // Create an <image> element and add it into svgElement
13        var imageElement = (SVGImageElement)document.CreateElementNS(SvgNamespace, "image");
14        imageElement.Href.BaseVal = "http://docs.aspose.com/svg/images/api/seaside.jpg";
15        imageElement.Height.BaseVal.Value = 480;
16        imageElement.Width.BaseVal.Value = 640;
17        imageElement.X.BaseVal.Value = 20;
18        imageElement.Y.BaseVal.Value = 20;
19        svgElement.AppendChild(imageElement);
20
21        // Create a <text> element, set its attributes, and it into svgElement
22        var textElement = (SVGTextElement)document.CreateElementNS(SvgNamespace, "text");
23        textElement.Style.FontSize = "1.4em";
24        textElement.SetAttribute("x", "420px");
25        textElement.SetAttribute("fill", "gold");
26        textElement.SetAttribute("y", "280px");
27        textElement.TextContent = "The beach is beautiful...";
28        svgElement.AppendChild(textElement);
29
30        // Create a <circle> element, set its attributes, and add it into svgElement
31        var circleElement = (SVGCircleElement)document.CreateElementNS(SvgNamespace, "circle");
32        circleElement.Cx.BaseVal.Value = 520;
33        circleElement.Cy.BaseVal.Value = 120;
34        circleElement.R.BaseVal.Value = 60;
35        circleElement.SetAttribute("stroke", "gold");
36        circleElement.SetAttribute("stroke-width", "70");
37        circleElement.SetAttribute("fill", "none");
38        circleElement.SetAttribute("stroke-dasharray", "2,14");
39        svgElement.AppendChild(circleElement);
40
41        // Save the document
42        document.Save(Path.Combine(OutputDir, "svg-drawing-on-bitmap.svg"));
43    }

Мы нарисовали круг SVG с большим значением ширины штриха. Применение атрибута stroke-dasharray преобразует обводку круга в пунктирную линию. Выбирая значения закрашенных-незакрашенных областей, можно добиться желаемого визуального эффекта. Дополнительную информацию о свойствах атрибутов стиля можно найти в статье Заливка и обводка в SVG.

Text «Изображение с добавленным текстом SVG и кружком SVG»

Вы можете загрузить полные примеры и файлы данных с GitHub. О загрузке с GitHub и запуске примеров вы узнаете из раздела Как запускать примеры.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.