GrapeCity
Published in

GrapeCity

How to Edit SVG Images Programmatically in C# .NET

This blog is the second in the series of articles related to programmatically creating and manipulating SVG images using the GcDocuments library for C# .NET.

In the last article, we discussed the need for programmatic creation of SVG images, the SVG drawing basics, the APIs available by GcDocs, and a simple walk-through of creating an SVG image from scratch.

But not all situations require creating images from scratch. More often than not, existing images can be transformed or customized to fit a particular business need. For instance:

  • change color or gradient to match the current theme or style of the document/website
  • flip, rotate or transpose
  • add or modify figures or shapes
  • scale the same image to fit multiple device screens and orientation

In this blog, we’ll see how we can manipulate an SVG image programmatically using C# .NET.

Use-Case

A company recently decided to change its logo to look more modern and innovative as part of the rebranding strategy. The designers suggested a new logo that is not much different from the current design. The new design can be achieved using a few tweaks and edits to the existing logo. You want to use this logo on your website, application, and mobile devices and need multiple copies for different sizes.

Creating these logos from scratch is not a cost-effective solution. So, the designer needs a way to programmatically manipulate the SVG image and generate multiple copies for different sizes with less effort.

For this blog, we will customize the GrapeCity Logo for the following and as shown below:

Current logo

In addition to this, we will generate the icon for the following layouts

  • Horizontal layout with dimensions 250 x 75 px
  • Vertical (Square) layout with dimensions 160 x 160 px

Let’s get started and look at the detailed steps to achieve the desired requirements using the GcImaging library for C# .NET.

Step 1 — Load an SVG document

The first step toward editing an image is loading it into the application. To load an SVG image using the GcImaging Libraries for C#.NET, import the namespace GrapeCity.Documents.Svg and use the FromFile method of the GcSvgDocuments class as in the code below:

using GrapeCity.Documents.Svg;
...
...
var svg = GcSvgDocument.FromFile(@"GrapeCityLogo.svg");

Step 2 — Modify the SVG content

Once you have loaded the SVG image to the SvgDocument, you can easily manipulate its DOM using the various classes, methods, and properties from the GcSvgDocuments class. Modifying the element for the color, position, or other settings, you must find/get the element using the GetElementById or GetElementByClass methods. When elements do not have an Id or class defined, you can traverse the nodes in the SVG’s XML, looking for the node you want to modify.

Let us see how we use these data structures to achieve the new logo’s requirements described above.

Change the color of elements

The color of an SVG element is changed using the Fill properties associated with the SVG elements. In the original logo file, the SVG elements have defined classes. Thus, we get the elements using the GetElementByClass method and change the color of the elements as depicted in the code below:

for (int i = 0; i <= 2; i++)
{
var el = svg.GetElementsByClass("st"+ i);
foreach (var e in el)
{
e.Fill = new SvgPaint(Color.FromArgb(56, 93, 171));
}
}​

Change icon position and add a border

With GcDocs, SVG elements are manipulated for the position, rotation, transpose, etc., using the SvgTransform class. This class is inherited in several transformation classes such as SvgTranslateTransform, SvgRotateTransform, SvgMatrixTransform, etc.

We changed the position of the logo’s image using the Translate transformation and added the border using the element’s Stroke property as depicted in the code below:

var elementLogo = svg.GetElementByID("logo");
elementLogo.Transform = new List<SvgTransform>()
{
new SvgTranslateTransform()
{
TranslateX = new SvgLength(14),
TranslateY = new SvgLength(2),
}
};
elementLogo.Fill = new SvgPaint(Color.FromArgb(102, 153, 204));
elementLogo.Stroke = new SvgPaint(Color.FromArgb(56, 93, 171));​

Rotate the alphabet “e” and a rectangle around it

Similar to the logo image, the element representing the alphabet “e” in the logo is rotated using the SvgRotateTransform class as shown below:

var elements = svg.GetElementsByClass("st1");
var elementE = elements[5];
if (elementE != null && elementE is SvgPathElement)
{
elementE.FillOpacity = 0.5f;
elementE.Transform = new List<SvgTransform>()
{
new SvgRotateTransform()
{
Angle = new SvgAngle(-30)
}
};
}

Drawing the rectangle around the alphabet “e” requires searching the parent node of the element “e” and adding a SvgRectElement to it, as shown in the code below:

var parent_of_elementE = elementE.Parent;
if (parent_of_elementE is SvgGroupElement g)
{
var rect = new SvgRectElement()
{
X = new SvgLength(109.6f, SvgLengthUnits.Pixels),
Y = new SvgLength(17.2f, SvgLengthUnits.Pixels),
Width = new SvgLength(16f, SvgLengthUnits.Pixels),
Height = new SvgLength(17.2f, SvgLengthUnits.Pixels),
StrokeWidth = new SvgLength(0.5f, SvgLengthUnits.Pixels),
Stroke = new SvgPaint(Color.FromArgb(56, 93, 171)),
Fill = new SvgPaint(SvgColor.Transparent)
};
g.Children.Add(rect);
}

Step 3 — Save the Image

When all the changes are applied, we save the image using the Save method from the GcSvgDocuments class as below:

svg.Save("GrapeCityLogo_New.svg");

Generate Images for different layouts

When working with images for a website or mobile application, you need the same image for several sizes and layouts. The same image may be required as a favicon, horizontal logo, square or vertical logo, logos for portrait or landscape orientations, and many such scenarios.

One can generate such SVG images quickly with the GcDocs libraries by configuring the SvgViewBox and/or Viewport.

For this blog, we generate a horizontal layout image with dimensions 250 x 75 px, as shown below, using the following code:

SvgViewBox view = new SvgViewBox();

svg.RootSvg.Width = new SvgLength(250, SvgLengthUnits.Pixels);
svg.RootSvg.Height = new SvgLength(75, SvgLengthUnits.Pixels);

view.MinX = 15;
view.MinY = 5;
view.Width = 180;
view.Height = 40;
svg.RootSvg.ViewBox = view;

svg.Save("GrapeCityLogo_Horizontal.svg");

And generate a vertical layout image with dimension 160 x 160 px as shown below, using the following code:

foreach (var node in svg.RootSvg.Children)
{
if(node is SvgGroupElement gr)
{
gr.Children.RemoveAt(1);
}
}

svg.RootSvg.Width = new SvgLength(160, SvgLengthUnits.Pixels);
svg.RootSvg.Height = new SvgLength(160, SvgLengthUnits.Pixels);

view.MinX = 20.5f;
view.MinY = 20;
view.Width = 36;
view.Height = 17;
svg.RootSvg.ViewBox = view;
svg.Save("GrapeCityLogo_Vertical.svg");

Here, we remove all the other elements from SVG DOM, keeping only the logomark to reduce the file size. You can choose to keep the elements and scale up the logomark to fit in the vertical logo dimension by configuring the view box and view port’s settings.

For further understanding, and to streamline your learning process be sure to download the complete sample!

Originally published at https://www.grapecity.com on May 6, 2022.

--

--

Sharing stories, concepts, and code.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
GrapeCity Developer Solutions

GrapeCity Developer Solutions

We provide developers with the widest range of Microsoft Visual Studio components, IDE platform development tools, and applications.