Modifier des fichiers SVG en C#

Aspose.SVG for .NET modifie le SVG comme un document vectoriel structuré. Chargez un fichier SVG dans un SVGDocument, recherchez ou créez des éléments SVG au moyen des API DOM, modifiez leur géométrie, leurs attributs, leur texte, leurs styles ou leurs données de chemin, puis enregistrez le fichier modifié sans le pixelliser.

Un flux de modification SVG type se déroule ainsi :

  1. Chargez un fichier SVG existant ou créez un nouveau SVGDocument.
  2. Recherchez un élément avec un sélecteur CSS ou créez-en un avec CreateElementNS().
  3. Modifiez les propriétés ou attributs et insérez le nouveau contenu dans l’arborescence SVG.
  4. Enregistrez le document SVG modifié avec Save().

Démarrage rapide : ajouter une forme à un fichier SVG

L’exemple suivant charge un fichier SVG, ajoute un cercle bleu à son élément racine <svg> et enregistre le document modifié :

 1using System.IO;
 2using Aspose.Svg;
 3
 4string inputPath = Path.Combine(DataDir, "shapes.svg");
 5string outputPath = Path.Combine(OutputDir, "shapes-with-circle.svg");
 6const string SvgNamespace = "http://www.w3.org/2000/svg";
 7
 8using (SVGDocument document = new SVGDocument(inputPath))
 9{
10    // Access the root <svg> element, which is present in an SVG document.
11    SVGSVGElement svgElement = document.RootElement;
12
13    // Create a circle and define its geometry and appearance.
14    SVGCircleElement circle = (SVGCircleElement)document.CreateElementNS(SvgNamespace, "circle");
15    circle.Cx.BaseVal.Value = 50;
16    circle.Cy.BaseVal.Value = 50;
17    circle.R.BaseVal.Value = 40;
18    circle.SetAttribute("fill", "#3A86FF");
19
20    // Add the circle to the document tree and save the edited SVG file.
21    svgElement.AppendChild(circle);
22    document.Save(outputPath);
23}

Si l’emplacement de l’élément à modifier n’est pas encore connu, consultez Inspecter et naviguer dans SVG pour des exemples avec des sélecteurs CSS et XPath. Pour les méthodes de chargement, consultez Créer et charger des documents SVG.

Ajouter des éléments et définir des attributs

La propriété RootElement renvoie l’élément racine <svg>. Les nouveaux éléments SVG doivent être créés dans l’espace de noms SVG ; vous pouvez ensuite les ajouter à un conteneur ou les insérer à un emplacement choisi dans l’arborescence du document.

Ce fragment crée un élément <g> et l’insère comme premier enfant de l’élément racine :

 1const string SvgNamespace = "http://www.w3.org/2000/svg";
 2
 3SVGSVGElement svgElement = document.RootElement;
 4SVGGElement groupElement = (SVGGElement)document.CreateElementNS(SvgNamespace, "g");
 5
 6// Apply common styles to every graphic element later added to the group.
 7groupElement.SetAttribute("fill", "#8A8D8F");
 8groupElement.SetAttribute("stroke", "magenta");
 9groupElement.SetAttribute("stroke-width", "4");
10
11svgElement.InsertBefore(groupElement, svgElement.FirstChild);

Utilisez SetAttribute() pour définir ou mettre à jour des attributs SVG comme fill, stroke, transform, class ou d sur des éléments créés ou existants.

Vous pouvez gérer les valeurs d’attributs avec les méthodes SetAttribute(name, value), GetAttribute(name), HasAttribute(name) et RemoveAttribute(name) de la classe Element.

Ajouter et modifier des formes SVG

Aspose.SVG for .NET fournit des classes DOM typées pour les formes SVG standard, notamment SVGCircleElement, SVGEllipseElement, SVGRectElement, SVGLineElement, SVGPolylineElement, SVGPolygonElement et SVGPathElement. Leurs propriétés typées permettent de modifier directement la géométrie : par exemple, Cx.BaseVal.Value, Cy.BaseVal.Value et R.BaseVal.Value définissent un cercle, tandis que le contenu reste vectoriel et modifiable.

Ajouter un cercle

Un cercle est contrôlé par les propriétés typées Cx, Cy et R. L’exemple complet suivant ajoute un cercle à un document SVG existant :

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

L’ellipse (Cx, Cy, Rx, Ry), le rectangle (X, Y, Width, Height, Rx, Ry) et la ligne (X1, Y1, X2, Y2) possèdent leurs propres attributs, qui se définissent de manière similaire.

Ajouter une polyligne et mettre à jour des formes existantes

L’élément SVG <polyline> stocke les coordonnées de ses sommets dans l’attribut points. Dans Aspose.SVG, la liste SVGPolylineElement.Points offre un accès typé à ces coordonnées. Avec CreateSVGPoint(), vous pouvez ajouter des points sans construire manuellement la chaîne d’attribut :

 1const string SvgNamespace = "http://www.w3.org/2000/svg";
 2
 3SVGSVGElement svgElement = document.RootElement;
 4SVGPolylineElement polylineElement = (SVGPolylineElement)document.CreateElementNS(SvgNamespace, "polyline");
 5
 6SVGPoint point1 = svgElement.CreateSVGPoint();
 7point1.X = 270;
 8point1.Y = 240;
 9SVGPoint point2 = svgElement.CreateSVGPoint();
10point2.X = 290;
11point2.Y = 220;
12SVGPoint point3 = svgElement.CreateSVGPoint();
13point3.X = 310;
14point3.Y = 240;
15
16polylineElement.Points.AppendItem(point1);
17polylineElement.Points.AppendItem(point2);
18polylineElement.Points.AppendItem(point3);
19polylineElement.SetAttribute("stroke", "grey");
20polylineElement.SetAttribute("stroke-width", "5");
21polylineElement.SetAttribute("fill", "none");
22
23// Add the new polyline to the SVG root element
24svgElement.AppendChild(polylineElement);
25
26// Update strokes of circle and ellipse elements already in the SVG document
27foreach (Element element in svgElement.Children)
28{
29    if (element is SVGCircleElement || element is SVGEllipseElement)
30    {
31        element.SetAttribute("stroke-width", "6");
32        element.SetAttribute("stroke", "#C8102E");
33    }
34}

L’image ci-dessous montre le fichier d’origine basic-shapes.svg et le résultat obtenu après l’ajout de formes et la modification des attributs de contour.

Formes SVG d’origine et formes SVG modifiées

Modifier les données d’un chemin SVG

La géométrie d’un élément <path> est stockée dans son attribut d. Créez un SVGPathElement typé, mettez à jour ses données de chemin et ajoutez-le au document SVG comme tout autre élément :

 1const string SvgNamespace = "http://www.w3.org/2000/svg";
 2
 3SVGPathElement pathElement =
 4    (SVGPathElement)document.CreateElementNS(SvgNamespace, "path");
 5
 6// Set the path geometry and its visible style.
 7pathElement.SetAttribute("d", "M 10 200 Q 25 210 180 200 T 300 250 T 420 250 T 490 150");
 8pathElement.SetAttribute("stroke", "magenta");
 9pathElement.SetAttribute("fill", "none");
10pathElement.SetAttribute("stroke-width", "4");
11
12document.RootElement.InsertBefore(pathElement, document.RootElement.FirstChild);

Si votre code construit ou ajuste les commandes de chemin segment par segment, SVGPathElement expose également des opérations sur les segments. L’exemple suivant crée un chemin et modifie les coordonnées de certaines commandes dans un fichier SVG existant :

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

La figure compare le chemin noir d’origine et le chemin rouge modifié. Vous pouvez également ouvrir le fichier d’exemple modifié : edit-svg-path-data.svg.

Chemin SVG d’origine et chemin SVG modifié

Pour la syntaxe des commandes de chemin et le comportement de dessin, consultez Données de chemin SVG.

Ajouter du contenu SVG sur une image bitmap

Un document SVG peut référencer une image raster avec un élément <image> et placer au-dessus du texte ou des formes vectorielles modifiables. Les pixels du bitmap ne sont pas modifiés : l’image d’arrière-plan et la superposition SVG restent des parties distinctes du document vectoriel.

Cette technique est utile lorsqu’une photo, un scan ou une autre ressource raster doit recevoir des libellés, marqueurs, badges ou éléments décoratifs qui restent modifiables en SVG. Dans SVG, l’ordre de dessin suit l’ordre des éléments : lorsque <image> est ajouté en premier, puis le texte ou les formes, les éléments vectoriels apparaissent par-dessus l’arrière-plan bitmap.

1<svg xmlns="http://www.w3.org/2000/svg">
2    <image href="/svg/images/api/seaside.jpg" height="480" width="640" x="20" y="20"/>
3    <text style="font-size: 1.4em;" x="420" y="280" fill="gold">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>

Pour créer cette composition avec Aspose.SVG for .NET :

  1. Créez un SVGDocument et accédez à son élément racine <svg> via RootElement.
  2. Créez un SVGImageElement avec CreateElementNS(), définissez la référence de l’image, sa position et sa taille, puis ajoutez-le à la racine en tant qu’arrière-plan.
  3. Créez un SVGTextElement, définissez le texte affiché, la position, le style de police et la couleur de remplissage, puis ajoutez-le après l’image.
  4. Créez un SVGCircleElement, définissez sa position, son rayon et ses attributs de contour, puis ajoutez-le après l’image d’arrière-plan. Dans cet exemple, un contour épais en tirets produit un effet décoratif rappelant le soleil.
  5. Appelez Save() pour écrire le document SVG. Le fichier enregistré conserve le bitmap référencé, le texte et le cercle sous forme d’éléments SVG modifiables.

L’exemple suivant effectue ces étapes et enregistre la sortie SVG :

1using Aspose.Svg;
2using System.IO;
3using Aspose.Svg.Paths;
 1// Draw SVG shapes and text on an existing bitmap in C#
 2
 3// Set the SVG namespace URI
 4string SvgNamespace = "http://www.w3.org/2000/svg";
 5
 6using (SVGDocument document = new SVGDocument())
 7{
 8    SVGSVGElement svgElement = document.RootElement;
 9
10    // Create an <image> element and add it into svgElement
11    SVGImageElement imageElement = (SVGImageElement)document.CreateElementNS(SvgNamespace, "image");
12    imageElement.Href.BaseVal = "http://docs.aspose.com/svg/images/api/seaside.jpg";
13    imageElement.Height.BaseVal.ConvertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX);
14    imageElement.Width.BaseVal.ConvertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX);
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 add it to the <svg> element
22    SVGTextElement 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 to the <svg> element
31    SVGCircleElement 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}

Pour en savoir plus sur la largeur du contour, les motifs de tirets et les autres attributs d’apparence SVG, consultez Remplissages et contours en SVG.

Arrière-plan bitmap avec texte SVG modifiable et cercle superposé

FAQ

1. La modification d’un fichier SVG avec Aspose.SVG le convertit-elle en bitmap ?

Non. La modification via SVGDocument change les éléments, attributs et données de chemin SVG, tandis que le document demeure vectoriel. Une sortie raster n’est produite que lorsque vous convertissez ou restituez explicitement le SVG vers un format d’image tel que PNG, JPEG ou WebP.

2. Comment modifier un élément SVG existant au lieu d’en ajouter un nouveau ?

Localisez l’élément voulu avec un sélecteur CSS ou une requête XPath, puis modifiez ses attributs ou ses propriétés SVG typées. Par exemple, après avoir sélectionné un <circle>, le code peut changer son rayon, sa position, son remplissage ou son contour. Consultez Inspecter et naviguer dans SVG et Modifier la couleur SVG.

3. Puis-je modifier un document SVG et convertir le résultat modifié dans le même flux ?

Oui. Chargez la source dans SVGDocument, effectuez les modifications, créez les options d’enregistrement du format cible et appelez Converter.ConvertSVG(document, options, outputPath). Utilisez par exemple PdfSaveOptions pour le PDF ou ImageSaveOptions pour PNG, JPEG, TIFF, GIF, BMP ou WebP. Consultez Convertir des fichiers SVG en C# pour des exemples complets.

4. Puis-je remplacer une forme SVG existante par un élément différent ?

Oui. Recherchez l’élément existant avec un sélecteur ou une requête XPath, créez l’élément de remplacement avec CreateElementNS(), insérez-le dans le même parent, puis supprimez l’ancien nœud. Le code peut par exemple remplacer des repères circulaires par des rectangles sans modifier le reste du document SVG. Consultez Inspecter et naviguer dans SVG pour un exemple.

Étapes suivantes