oneimage

Convert SVG to PNG in C#

Convert SVG to PNG, JPG, WebP or ICO in C# with pure .NET code: render at any size, read the natural size, ship your own fonts and handle untrusted SVG safely.

To convert an SVG to PNG in C#, add the RecursiveAI.OneImage.Svg package, register its SVG format, load the file and save it with a .png extension. The SVG is rendered at the size you ask for, so a 24-pixel icon becomes a sharp 512-pixel PNG instead of an upscaled blur. It is pure C#, with no Skia, Cairo or System.Drawing underneath, so the same code runs on Windows, Linux, macOS and in containers. Below: rendering at a given width, natural size, icon sets and favicons, fonts, JPG output, SVG from a string, and untrusted files. Every sample was run against OneImage 1.6.0 and OneImage.Svg 1.6.0 on .NET 10.

TerminalNuGet
dotnet add package RecursiveAI.OneImage.Svg

The package brings in OneImage and OneImage.Text, which draws SVG text, and targets .NET 10. All three are licensed MIT OR Apache-2.0. The examples use Wikipedia’s public-domain flag of the United States SVG, which declares width="1235" height="650", plus a small icon and a badge of our own.

Convert an SVG file to PNG

Program.cs.NET 10
using OneImage;
using OneImage.Svg;

// SVG support is a separate package: register its format for the load call.
var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(SvgFormat.Instance)
};

Image.Load("flag-us.svg", options).Save("flag-us.png");

This writes a 1235×650 PNG with a transparent background wherever the SVG paints nothing. As with PDF, the SVG format isn’t in OneImage’s default configuration because it lives in a separate package, so you add it to the configuration you pass to Load. Save as .webp, .jpg, .gif, .tif or .bmp to get those formats instead.

Render the SVG at a specific size

Program.cs.NET 10
using OneImage;
using OneImage.Svg;

var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(SvgFormat.Instance)
};

// Drawn at 2400 px wide, not rendered at 1235 px and scaled up.
Image.Load("flag-us.svg", options).Resize(width: 2400).Save("flag-us-2400.png");

The result is 2400×1263: the height follows the aspect ratio and rounds to the nearest pixel. When a resize sits directly on a loaded SVG, OneImage passes the target size to the renderer, so curves and edges are drawn at 2400 px rather than enlarged from a 1235 px raster. Give a height instead, or both with a fit:, exactly as for photos. Our guide to resizing images in C# covers the fit modes.

Get the natural size of an SVG

Program.cs.NET 10
using OneImage;
using OneImage.Svg;

var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(SvgFormat.Instance)
};

ImageInfo info = Image.Identify("flag-us.svg", options);
Console.WriteLine($"{info.Width}x{info.Height}");

It prints 1235x650. Identify reads only the root element’s start tag. Per the OneImage.Svg documentation, the natural size in CSS pixels (96 per inch) works like this:

An icon with only viewBox="0 0 24 24" is 24×24.

Make app icons and a favicon from one SVG

Program.cs.NET 10
using OneImage;
using OneImage.Svg;

var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(SvgFormat.Instance)
};
Image icon = Image.Load("icon.svg", options);

foreach (int size in new[] { 32, 180, 192, 512 })
{
    icon.Resize(width: size, height: size).Save($"icon-{size}.png");
}

icon.Resize(width: 32, height: 32).Save("favicon.ico");

From our 24×24 icon this wrote 32, 180, 192 and 512 px square PNGs, each drawn at its own size, and a 32×32 favicon.ico. The loaded Image is immutable, so one load feeds every size.

Text and fonts in SVG

SVG text is drawn with real fonts: font-family lists, weights, styles, kerning, ligatures, textPath, and right-to-left and complex scripts through OneImage.Text. By default the renderer looks up the fonts installed on the machine. For output that is the same on every machine, including containers that have no fonts, add the font files you ship and turn off the system lookup:

Program.cs.NET 10
using OneImage;
using OneImage.Svg;

// Draw text with a font you ship, the same on every machine.
var fonts = new SvgFontOptions { UseSystemFonts = false };
fonts.AddFont("NotoSans-Regular.ttf");

var svg = new SvgFormat(SvgLimits.Default, ["en"], fonts);
var options = new LoadOptions { Configuration = new ImageConfiguration().Add(svg) };

Image.Load("badge.svg", options).Resize(width: 640).Save("badge.png");

Our badge, a gradient rectangle with a drop-shadow filter and the text “build passing” in Noto Sans, rendered to a 640×240 PNG. We published the same program and ran it in the stock mcr.microsoft.com/dotnet/runtime:10.0 image, which has no fonts installed, and got a PNG identical to the one made on our workstation. AddFont takes TrueType, OpenType, collections, WOFF and WOFF2, from a file, a stream or bytes. FallbackFamilies and SetGenericFamily control what sans-serif and missing characters resolve to.

Convert SVG to JPG

Program.cs.NET 10
using OneImage;
using OneImage.Svg;

var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(SvgFormat.Instance)
};

// SVG renders on a transparent background; JPEG has no alpha, so put it on white first.
Image.Load("icon.svg", options)
     .Resize(width: 600)
     .Flatten(new Rgba32(255, 255, 255, 255))
     .Save("icon.jpg");

Without Flatten, transparent areas would be written with whatever color values they store. With it, the 600×600 JPEG has the icon on white.

Render an SVG string from memory

SVG is a convenient way to generate charts, badges and placeholders in code. Build the markup as a string and load the bytes, with no temporary file:

Program.cs.NET 10
using System.Text;
using OneImage;
using OneImage.Svg;

var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(SvgFormat.Instance)
};

int percent = 72;
string svg = $"""
    <svg xmlns="http://www.w3.org/2000/svg" width="200" height="20">
      <rect width="200" height="20" rx="4" fill="#e5e7eb"/>
      <rect width="{percent * 2}" height="20" rx="4" fill="#16a34a"/>
    </svg>
    """;

byte[] bytes = Encoding.UTF8.GetBytes(svg);
Image.Load(bytes, options).Resize(width: 400).Save("progress.png");

This writes a 400×40 progress bar at 72%. Image.Load also takes a Stream, for SVG coming from a request or blob storage.

What SVG features render

The OneImage.Svg documentation lists the full scope. It covers static SVG 1.1 and the SVG 2 and CSS features documents use in practice:

Converting untrusted SVG files safely

SVG is XML that can point at other resources, so converting user uploads needs care. OneImage.Svg is built for that:

How fast is it?

The OneImage repository publishes SVG benchmarks against Svg.Skia 5.2.3. For a 1000×800 illustration of about 3,000 shapes drawn at 1024 px wide, load plus render took 25.2 ms with OneImage and 78.7 ms with Svg.Skia. For a 24×24 icon drawn at 256 px, it took 141 µs against 363 µs. Those are BenchmarkDotNet means (short job) on an AMD Ryzen 9 7950X3D with .NET 10.0.13, on a shared machine that was under load during the run. The status section of the SVG documentation has the full table, including allocations and render-only times.

Other ways to convert SVG to PNG in C#

For PDF pages, the same approach works with OneImage.Pdf; see converting PDF to images in C#. For smaller web output, save the rendered SVG as WebP; our guide to converting images to WebP covers quality and lossless settings.