Supply linked images when reading SVG

View as Markdown

Format ConversionGraphics ContainerPDFSVG

This sample shows how to read an SVG whose images are not next to it, for example a design from an online editor that refers to its pictures by URL. The SvgReaderSettings.ResolveImage callback is called for every image element; it gets the reference through ResolveImageArgs.Href and supplies the content itself: a raster image through ResolveImageArgs.Image or vector graphics through ResolveImageArgs.GraphicsContainer. Here a photo comes from a local cache as a CompressedImage, so its JPEG data reaches the output PDF unchanged, and a seal comes from a PDF file and stays vector.

Code Snippet

// Local copies of the assets that the SVG refers to by URL.
var assets = new Dictionary<string, string>
{
    ["https://cdn.example.com/products/apple.jpg"] = "Apple.jpg",
    ["https://cdn.example.com/seals/notary.pdf"] = "Seal.pdf",
};

var settings = new SvgReaderSettings
{
    ResolveImage = args =>
    {
        if (!assets.TryGetValue(args.Href, out var fileName))
        {
            // Leaving both Image and GraphicsContainer unset loads the reference as usual.
            return;
        }

        Console.WriteLine("{0} -> {1}", args.Href, fileName);

        if (fileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
        {
            // Vector graphics stay vector.
            using (var pdfReader = new PdfReader(fileName))
            using (var seal = pdfReader.Frames[0].GetContent())
            {
                args.GraphicsContainer = seal;
            }
        }
        else
        {
            // The JPEG data is kept and written to the PDF without recompression.
            using (var photo = CompressedImage.CreateFromFile(fileName))
            {
                args.Image = photo;
            }
        }
    },
};

using (var reader = new SvgReader("Certificate.svg", settings))
using (var writer = new PdfWriter("ResolveSvgImages.pdf"))
using (var graphics = writer.GetGraphics())
using (var content = reader.GetContent())
{
    writer.AddPage(reader.Width, reader.Height, reader.DpiX, reader.DpiY);
    graphics.DrawContainer(content, 0, 0);
}

Input

Certificate.svg

Certificate.svg

Apple.jpg

Download

Seal.pdf

Download

Output

ResolveSvgImages.pdf

Download

ResolveSvgImages.png

ResolveSvgImages.png

ResolveSvgImages.txt

https://cdn.example.com/products/apple.jpg -> Apple.jpg
https://cdn.example.com/seals/notary.pdf -> Seal.pdf

Used APIs