How to save inline SVG as PNG with vanilla Javascript and html canvas

February 17, 2021 ≈ 1 minute 30 seconds

Imagine, you loaded an SVG file from the database and displayed it on the page. How to convert it to PNG? How to make download links?

Nowadays, with modern browsers (bye-bye IE, I would never miss you) and html canvas, this is pretty simple, even using vanilla Javascript.

Code below tested in the latest desktop Chrome and Firefox. Safari at this moment prevents toDataURL() on the inline SVG's, so as iOS Safari and Chrome.
First let's write a little helper, which would help us to download files. Basically, it creates <a> element with href and clicks it.

function download(href, name)
{
    var a = document.createElement('a');

    a.download = name;
    a.href = href;

    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

Let's download inline SVG, using this method

download(window.URL.createObjectURL(new Blob(['code of inline SVG'], {type: 'image/svg'})), 'svg');

Not that hard... Now let's convert inline SVG to PNG and download it

function downloadPNG()
{
    // specify png with and height in pixels
    var png_width = 1024;
    var png_height = 768;

    var inline_svg = ''; // code of inline SVG

    var canvas = document.createElement("canvas"); // create <canvas> element
    // The 2D Context provides objects, methods, and properties to draw 
    // and manipulate graphics on a canvas drawing surface.
    var context = canvas.getContext("2d");

    // set canvas with and height equal to png with and height
    canvas.width = png_width;
    canvas.height = png_height;

    let image = new Image; // create <img> element
    image.onload = function () {
        // define fill (specify 'no-repeat' if you don't want it to repeat
        context.fillStyle = context.createPattern(image, 'repeat'); 
        // fill rectangle with defined fill
        context.fillRect(0, 0, canvas.width, canvas.height); 
        this.download(canvas.toDataURL("image/png"), 'example.png');
    }.bind(this);

    // btoa — binary string to ASCII (Base64-encoded)
    image.src = 'data:image/svg+xml;base64,' + btoa('inline svg'); 
}

That's it! If you want more tips like this, subscribe to our newsletter and follow Daily Web Dev on twitter.

Subscribe to our newsletter

If you provide url of your website, we send you free design concept of one element (by our choice)

Subscribing to our newsletter, you comply with subscription terms and Privacy Policy