public void EndUpdate() The user can modify the elements of an SVG document using EnumerateElements and update the node's elements or attributes.
After modifying the values of an SVG document using SvgNodeHandle, it may be necessary to re-calculate the document flat, render optimization and bounding rectangles (refer to SVG Size, Bounds and Flat more information). Therefore, it is best to call BeginUpdate before making any updates to the document and to call EndUpdate when finished. The engine will check during EndUpdate if any internal state values need to be re-calculated and updated as necessary.
BeginUpdate increments an internal counter and EndUpdate decrements it. When the counter reaches 0 again, the document is updated. Therefore, the user can chain calls to BeginUpdate / EndUpdate pair and the update will only occur once at the end.
using Leadtools;using Leadtools.Codecs;using Leadtools.Drawing;using Leadtools.Forms.DocumentWriters;using Leadtools.Svg;using Leadtools.Document.Writer;private static void SvgDocumentEnumerateElementsExample(){// The source PDF filevar sourceFile = $@"{LEAD_VARS.ImagesDir}\Leadtools.pdf";var beforeSvgFile = $@"{LEAD_VARS.ImagesDir}\Leadtools_before.svg";var afterSvgFile = $@"{LEAD_VARS.ImagesDir}\Leadtools_after.svg";// Assume this is our Virtual Directoryvar virtualDirectory = "http://localhost/leadtools_images/svg/resources";// Assume this phrysical directory maps to the Virtual Directoryvar physicalDirectory = $@"{LEAD_VARS.ImagesDir}\svg\resources";if (!Directory.Exists(physicalDirectory))Directory.CreateDirectory(physicalDirectory);// Our SVG element enumartion callbackSvgEnumerateElementsCallback callback = (SvgDocument document, SvgNodeHandle node, object userData) =>{if (node.ElementType == SvgElementType.Image){// Get the hrefvar href = node.GetAttributeValue("xlink:href");if (!string.IsNullOrEmpty(href)){// Parse it as data URIvar dataUri = SvgDataUri.Parse(href);// Check if it is a data URIif (dataUri.IsDataUri){// Yes, create a new file in a virtual directory// Show the dataURI propertiesConsole.WriteLine("Replacing data URI");Console.WriteLine("Format:" + dataUri.ImageFormat);if (dataUri.MediaLength > 0)Console.WriteLine("Media:" + dataUri.Href.Substring(dataUri.MediaOffset, dataUri.MediaLength));if (dataUri.CharSetOffset > 0)Console.WriteLine("CharSet:" + dataUri.Href.Substring(dataUri.CharSetOffset, dataUri.CharSetLength));elseConsole.WriteLine("CharSet: not set");Console.WriteLine("IsBase64:" + dataUri.IsBase64);Console.WriteLine("ImageFormat:" + dataUri.ImageFormat);var extension = dataUri.Extension;Console.WriteLine("Extension:" + dataUri.Extension);// Get a file namevar name = Guid.NewGuid().ToString().Replace("-", "") + "." + dataUri.Extension;// Save it// Full physical pathvar filePath = Path.Combine(physicalDirectory, name);dataUri.DecodeToFile(filePath);/* Alternatively you can save the data yourself using this codevar data = dataUri.Href.Substring(dataUri.ValueOffset, dataUri.ValueLength);// Save the datavar base64String = dataUri.Href.Substring(dataUri.ValueOffset, dataUri.ValueLength);byte[] rawData = Convert.FromBase64String(base64String);// Save it to diskFile.WriteAllBytes(filePath, rawData);*/// Finally replace the attribute in the image element with the URIvar virtualPath = virtualDirectory + "/" + name;node.SetAttributeValue("xlink:href", virtualPath);}else{Console.WriteLine("Does not contain a valid data URI.");}}}return true;};using (var rasterCodecs = new RasterCodecs()){// Use 300 DPI when loading document imagesrasterCodecs.Options.RasterizeDocument.Load.Resolution = 300;// Load the first page as SVGusing (var svg = rasterCodecs.LoadSvg(sourceFile, 1, null) as SvgDocument){if (!svg.IsFlat)svg.Flat(null);if (!svg.Bounds.IsValid)svg.CalculateBounds(false);// Save this SVG to disk, report the sizesvg.SaveToFile(beforeSvgFile, null);Console.WriteLine("Before unembedding the image, size is " + new FileInfo(beforeSvgFile).Length);// Now enumerate the elements to replace each embedded image with a URL// Since we are going to modify the SVG, call BeginUpdate/EndUpdate to speed up the processsvg.BeginUpdate();svg.EnumerateElements(new SvgEnumerateOptions { EnumerateDirection = SvgEnumerateDirection.TopToBottom }, callback, null);svg.EndUpdate();// Save this SVG to disk again, report the size, should be alot smaller since the image are unembedded and stored as external resourcessvg.SaveToFile(afterSvgFile, null);Console.WriteLine("Before unembedding the image, size is " + new FileInfo(afterSvgFile).Length);}}}static class LEAD_VARS{public const string ImagesDir = @"C:\LEADTOOLS22\Resources\Images";}