Introduction

Scalable vector graphics(SVG), has been widely popular currently in terms of rendering web graphics. When compared with Raster images, Vector images (SVG image types) have the following advantages.

  • As the proper name implies Vector SVG graphics are scaleable and do non pixelate at higher zoom levels.
  • Vector image scaled
    Vector prototype scaled
    Raster image pixelated after resizing
    Raster image pixelated later on resizing
  • Vector graphics are formed using bones shapes, mathematical paths and lines. Because of this it is easier to understand sub parts that brand upward the vector epitome.
  • SVG files are XML files therefore customizing them and making changes is easier than manipulating binary raster images.

Practical Usages of Vector Images

  • To stand for dynamic charts
  • SVG graphics are been used for dynamic interactive charts. This is mainly due to its ease of scalability and the ease in creating interactive graphics. Since as above mentioned, SVG graphics allows to place sub parts of the graphic therefore allows to customize a graph and its sub components easily.

  • To stand for icons in a Map or a floorplan
  • When in a scenario where y'all need to create 100 to 1000s of icons annotating a map and to allow scaling and zooming into these icons the best choice is to use SVG images. also these allow to dynamically color the icons to comment regions of a map and to toggle on/off the icons on a map with ease.

Using Vector images in C#

Lets now bank check simple manipulation of SVG images using C#. Fifty-fifty though the .Internet framework does not consist of out of the box implementations to manipulate SVG images, we could brand use of a more usable framework known every bit SVG Render Engine

SVG Render Engine

Creating a sample awarding in C#

To identify the features explained above lets start of with a simple .Internet Windows application. The awarding would consists of the following features.

  • Loading and converting a SVG graphic to a raster image and drawing information technology in C# forms controls.
  • Using recursive approaches to place paths in the SVG graphic consisting of a given make full color.
  • Identifying the fill colors and replacing fill colors.
  • Scaling a SVG graphics based on limit boundaries.

Offset off by creating a new C# Forms application and then install the SVG Return library equally reference using the Nuget Package Director.
Right click on the Project from the Solutions Explorer and select Manage Nuget Packages from the online section in the left console start searching for SVG Render Library

Installing the SVG Render Library

Once the packet has been installed create a basic form as beneath. The controls used in the form are more often than not text boxes and buttons. The bottom part of the form consists of a canvas area, a panel containing a picturebox. This picturebox would be used to return out the rendered SVG image. The Option Color control is used as a toggle push button, a checkbox with a flat button view to see if its clicked or not. This push toggles a state where you lot could option colors from a loaded SVG image.

Other than the basic components, a ColorDialog and a OpenFileDialog is used to load a color picker and to help in loading a SVG file into the canvas.

SVG Sample Form

Usage of the application

The following screenshots bear witness the usage of the functions of the sample application to get a more clearer idea.

Instructions Screen

Initially once the awarding has been launched, use the browse push button to load a sample SVG image into the picturebox.

After loading a SVG Image
Subsequently loading a SVG Image

Click the Pick Color to start color option mode. To select a color motion the cursor over a desired pixel on the canvas area beneath (the cursor pointer would plough to a cross) click once y'all come to the desired area. (In this instance the green color of the eyes have been selected).Adjacent click on the destination color swatch to load the color picker and pick the desired replacement color.

Picking a source color from the picture box
Picking a source colour/Destination color
Click Replace Colour to supercede the selected source color with the destination color. Annotation that all areas with the source color every bit fill color would be replaced in the epitome.
Replacing the source color picked with a destination color
Replacing the source color picked with a destination colour
Scaling the image is also possible using the Scale up/calibration downwards controls. Notice how the epitome is not blurry during the scaling process and remains sharp and crisp.
Scaling SVG images
Scaling SVG images

When using the SVG render library, the starting bespeak is to load the SVG paradigm into a SvgDocument. One time the SvgDocument object is created there would be SvgElement objects. SvgElement is the super type of all of the other specific SVG element types such every bit SvgPath, SvgText, SvgCircle, SvgEcllipse. When traversing through the SvgDocument these elements tin be extracted based on their type.

The application contains a split up course to concur the SVG manipulation lawmaking. Since the picture box is of a stock-still size the SvgParser consists of proportionately resizing the SVG image to properly fit the picturebox.

SVGSample.svg.SVGParser.cs

using System; using Organization.Collections.Generic; using System.Drawing; using Arrangement.Linq; using System.Text; using System.Threading.Tasks; using Svg;  namespace SVGSample.svg {     /// <summary>     /// Course containg code for manipulating SVG graphics.     /// </summary>     public grade SVGParser     {         /// <summary>         /// The maximum prototype size supported.         /// </summary>         public static Size MaximumSize { get; set; }          /// <summary>         /// Converts an SVG file to a Bitmap paradigm.         /// </summary>         /// <param name="filePath">The full path of the SVG image.</param>         /// <returns>Returns the converted Bitmap image.</returns>         public static Bitmap GetBitmapFromSVG(string filePath)         {             SvgDocument document = GetSvgDocument(filePath);                       Bitmap bmp=document.Draw();             return bmp;         }          /// <summary>         /// Gets a SvgDocument for manipulation using the path provided.         /// </summary>         /// <param proper noun="filePath">The path of the Bitmap image.</param>         /// <returns>Returns the SVG Document.</returns>         public static SvgDocument GetSvgDocument(string filePath)         {             SvgDocument document=SvgDocument.Open(filePath);             return AdjustSize(document);         }          /// <summary>         /// Makes sure that the image does non exceed the maximum size, while preserving aspect ratio.         /// </summary>         /// <param proper noun="certificate">The SVG document to resize.</param>         /// <returns>Returns a resized or the original certificate depending on the document.</returns>         private static SvgDocument AdjustSize(SvgDocument document)         {             if (document.Top > MaximumSize.Height)             {                 document.Width = (int)((document.Width / (double)document.Height) * MaximumSize.Height);                 document.Top = MaximumSize.Height;             }             return document;         }      }  }        

Next lets have a wait at the event bindings of the form. There are events for all of the push button controls, A mouse downwardly event for the Picturebox to track the pixel color under the current mouse position. Notice the usage of the GDI raster graphics classes found in .NET to go the pixel color using GetPixel. A validation method is used to bank check if an SVG image has been loaded prior to using the other functions, this is the ValidateFormControls.

ChangeFill is a recursive method, which traverses through the entire XML SVG document, from element to element and checks the make full color whether it matches a given color, if so replaces with the provided replace color. It is important to note that nosotros option the color from the raster image in the Picturebox every bit the source and matches it against the svg document for matching fill colors. This shows that the raster image consists of the same colors without a quality loss when converting from SVG.

SVGSample.frmSVGWindow.cs

          /// <summary>         /// The file path of the SVG image selected.         /// </summary>         individual string selectedPath;          /// <summary>         /// Case reference for the svgDocument used and updated throughout the manipulation of the image.         /// </summary>         private Svg.SvgDocument svgDocument;                  /// <summary>         /// Form window constructor.         /// </summary>         public frmSVGWindow()         {             InitializeComponent();         }          /// <summary>         /// Destination Color Selection         /// </summary>         /// <param name="sender">The source calling the result.</param>         /// <param name="e">The arguments passed to the upshot.</param>         private void btnDestinationColor_Click(object sender, EventArgs e)         {             DialogResult result = colorPicker.ShowDialog();             if (result == DialogResult.OK)             {                 btnDestinationColor.BackColor = colorPicker.Color;             }         }          /// <summary>         /// Action responsible to allow the user select a SVG image.         /// </summary>         /// <param name="sender">The source calling the event.</param>         /// <param name="east">The arguments passed to the event.</param>         private void btnBrowse_Click(object sender, EventArgs e)         {             DialogResult selectResult = filePicker.ShowDialog();             if (selectResult == System.Windows.Forms.DialogResult.OK)             {                 svg.SVGParser.MaximumSize = new Size(pictConvertedImage.Width, pictConvertedImage.Height);                                  selectedPath = filePicker.FileName;                 txtSelectedFile.Text = selectedPath;                 svgDocument = svg.SVGParser.GetSvgDocument(selectedPath);                                 txtWidth.Text = svgDocument.Width.Value.ToString();                 txtHeight.Text = svgDocument.Height.Value.ToString();                                   pictConvertedImage.Image = svg.SVGParser.GetBitmapFromSVG(selectedPath);             }         }          /// <summary>         /// Action responsible to allow the user choice a source colour.          /// </summary>         /// <param proper name="sender">The source calling the event.</param>         /// <param proper noun="east">The arguments passed to the issue.</param>         private void btnSourceColor_Click(object sender, EventArgs e)         {             colorPicker.ShowDialog();         }          /// <summary>         /// Activity responsible to supercede the color of the original image.         /// </summary>         /// <param name="sender">The source calling the effect.</param>         /// <param name="e">The arguments passed to the result.</param>         private void btnReplaceColor_Click(object sender, EventArgs e)         {             if (!ValidateFormControls())             render;              foreach (Svg.SvgElement item in svgDocument.Children)             {                 ChangeFill(item, btnSourceColor.BackColor, btnDestinationColor.BackColor);             }             pictConvertedImage.Image = svgDocument.Draw();          }          /// <summary>         ///  Recursive fill function to change the color of a selected node and all of its children.         /// </summary>         /// <param name="chemical element">The current element been resolved.</param>         /// <param name="sourceColor">The source color to search for.</param>         /// <param name="replaceColor">The colour to exist replaced the source color with.</param>         private void ChangeFill(SvgElement chemical element, Color sourceColor, Color replaceColor)         {             if (chemical element is SvgPath)             {                 if (((element as SvgPath).Fill as SvgColourServer).Colour.ToArgb() == sourceColor.ToArgb())                 {                     (element as SvgPath).Fill = new SvgColourServer(replaceColor);                 }             }              if (element.Children.Count > 0)             {                 foreach (var item in element.Children)                 {                     ChangeFill(item, sourceColor, replaceColor);                 }             }          }                               /// <summary>         /// Activeness used to pick the color from a pixel from the rasterized motion picture.         /// </summary>         /// <param name="sender">The source calling the upshot.</param>         /// <param name="due east">The arguments passed to the result.</param>         private void pictConvertedImage_MouseDown(object sender, MouseEventArgs east)         {             if (togglePickColor.Checked)             {                 if (!ValidateFormControls())                     return;                   if (e.Push == Arrangement.Windows.Forms.MouseButtons.Left)                 {                     Bitmap bmp = pictConvertedImage.Epitome as Bitmap;                     btnSourceColor.BackColor = bmp.GetPixel(e.X, e.Y);                  }             }         }          /// <summary>         /// Action used to scale down an SVG image. (in inrements of ten)         /// </summary>         /// <param proper noun="sender"></param>         /// <param name="east"></param>         private void btnScaleDown_Click(object sender, EventArgs e)         {             if (!ValidateFormControls())                 return;              int Due west =int.Parse(txtWidth.Text);             int H = int.Parse(txtHeight.Text);              if (Westward - x > 0 &&  H- 10 > 0)             {                 W -= 10;                 txtWidth.Text = W.ToString();                  H -= ten;                 txtHeight.Text = H.ToString();                  svgDocument.Width = W;                 svgDocument.Elevation = H;                  pictConvertedImage.Prototype = svgDocument.Draw();             }         }          /// <summary>         /// Action used to scale upwards an SVG image. (in inrements of 10)         /// </summary>         /// <param name="sender">The source calling the issue.</param>         /// <param name="e">The arguments passed to the event.</param>         private void btnScaleUp_Click(object sender, EventArgs e)         {             if (!ValidateFormControls())                 return;              int Due west = int.Parse(txtWidth.Text);             int H = int.Parse(txtHeight.Text);              if (W + 10 < pictConvertedImage.Width && H + x < pictConvertedImage.Height)             {                 W += 10;                 txtWidth.Text = W.ToString();                  H += 10;                 txtHeight.Text = H.ToString();                  svgDocument.Width = Due west;                 svgDocument.Height = H;                  pictConvertedImage.Epitome = svgDocument.Depict();             }         }          /// <summary>         /// Checks if in that location is an paradigm selected.         /// </summary>         /// <returns>Returns the boolean results whether an paradigm is selected.</returns>         private bool ValidateFormControls()         {             if (svgDocument == null || pictConvertedImage.Image == nix)             {                 MessageBox.Bear witness("Delight select a SVG epitome to continue");                 return false;             }             return true;         }          /// <summary>         /// Action performed to indicate whether picking colour from the paradigm is available.         /// </summary>         /// <param proper noun="sender">The source calling the result.</param>         /// <param name="east">The arguments passed to the upshot.</param>         private void togglePickColor_CheckedChanged(object sender, EventArgs east)         {             if (togglePickColor.Checked)             {                 togglePickColor.BackColor = Color.LightPink;                 pictConvertedImage.Cursor = Cursors.Cross;             }             else             {                 togglePickColor.BackColor = Color.Gainsboro;                 pictConvertedImage.Cursor = Cursors.Default;             }         }        

Image Reference – Blackicemedia.com awesome tiger.
To download the code sample use the link below
Download Sample Code

That concludes this cursory introduction to SVG manipulation using the SVG Render Engine Library. Do check out more at Codeplex
for other functionality supported in the library.