DEV Community

Michael Lip
Michael Lip

Posted on • Originally published at zovo.one

Converting SVG to PNG Without Quality Loss: The Details That Matter

SVG is the right format for the web. PNG is the right format for everything else -- social media uploads, email clients, document embeds, and any context where the rendering environment does not support vector graphics. The conversion seems trivial, but the details determine whether your output looks crisp or blurry.

Why resolution matters more than you think

An SVG has no inherent pixel dimensions. It has a viewBox that defines a coordinate system. When you convert to PNG, you must choose pixel dimensions. If your SVG has a viewBox of 0 0 200 200 and you export at 200x200px, you get a 1:1 mapping. On a 2x retina display, that image looks blurry because it is being upscaled.

For sharp rendering on modern displays, export at 2x or 3x the intended display size. A 200x200 viewBox should become a 400x400 or 600x600 PNG. Anything below 2x will look soft on high-DPI screens.

For print, the math changes entirely. Print resolution is typically 300 DPI. If your SVG is intended to print at 2 inches wide, you need 2 * 300 = 600 pixels. At 72 DPI (screen resolution), that same 2 inches is only 144 pixels. Getting the DPI wrong means either pixelated prints or unnecessarily large files.

The Canvas API approach

The standard browser-based conversion uses the Canvas API:

function svgToPng(svgString, width, height) {
  return new Promise((resolve) => {
    const img = new Image();
    const blob = new Blob([svgString], { type: 'image/svg+xml' });
    const url = URL.createObjectURL(blob);

    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, width, height);
      URL.revokeObjectURL(url);
      resolve(canvas.toDataURL('image/png'));
    };

    img.src = url;
  });
}
Enter fullscreen mode Exit fullscreen mode

This works, but has limitations. External resources (fonts, images) referenced in the SVG may not load due to CORS restrictions. CSS stylesheets that target SVG elements from the parent document will not apply inside the canvas rendering context.

Font handling is the hardest part

If your SVG uses a web font, the Canvas API will substitute a fallback font unless the font is either embedded in the SVG or already loaded in the document.

The solution is to embed the font directly in the SVG before conversion:

<defs>
  <style>
    @font-face {
      font-family: 'Inter';
      src: url(data:font/woff2;base64,...) format('woff2');
    }
  </style>
</defs>
Enter fullscreen mode Exit fullscreen mode

Base64 encoding the font inside the SVG guarantees it renders correctly regardless of the conversion environment. The downside is that the SVG becomes much larger (a typical font subset is 20-50KB base64), but this is only for the conversion step.

Background transparency

PNGs support transparency. SVGs render on a transparent background by default. If you want a white background in your PNG, you need to explicitly draw it:

ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
Enter fullscreen mode Exit fullscreen mode

This is frequently overlooked. People convert an SVG icon to PNG, upload it somewhere with a dark background, and discover the icon was transparent where they expected white.

Batch conversion scenarios

Design systems often need to export an entire icon set as PNGs at multiple sizes (16px, 24px, 32px, 48px) from SVG sources. Doing this manually in a design tool is tedious. Scripting it with the Canvas API or a headless browser is the scalable approach.

I built an SVG to PNG converter at zovo.one/free-tools/svg-to-png-converter that handles custom dimensions, scale factors, background color, and font embedding. Upload or paste your SVG, set the output parameters, and download a crisp PNG. It handles the edge cases so you do not have to debug canvas rendering quirks.

I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.

Top comments (0)