Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SVG to PNG
var svg = document.querySelector( "svg" );
var svgData = new XMLSerializer().serializeToString( svg );
var canvas = document.createElement( "canvas" );
var ctx = canvas.getContext( "2d" );
var img = document.createElement( "img" );
img.setAttribute( "src", "data:image/svg+xml;base64," + btoa( svgData ) );
img.onload = function() {
ctx.drawImage( img, 0, 0 );
// Now is done
console.log( canvas.toDataURL( "image/png" ) );
};
@abishekrsrikaanth

This comment has been minimized.

Copy link

@abishekrsrikaanth abishekrsrikaanth commented Jun 11, 2014

Is there a way to convert PNG to SVG?

@gustavohenke

This comment has been minimized.

Copy link
Owner Author

@gustavohenke gustavohenke commented Jun 17, 2014

Not that I'm aware of.
PNG is a raster image type, while SVG is a vector.

@amergin

This comment has been minimized.

Copy link

@amergin amergin commented Jul 4, 2014

Note that currently this solution does not work in Firefox. Chrome seems to support this ok. I'm also thinking that the onload function should probably be defined before setting the image src.

@philfreo

This comment has been minimized.

Copy link

@philfreo philfreo commented Aug 22, 2014

To have the image not be cropped, you just need to set the size of the convas, which you can do based on the size of the svg.

Just put this immediately after var canvas = ...

        var svgSize = svg.getBoundingClientRect();
        canvas.width = svgSize.width;
        canvas.height = svgSize.height;
@shreyashah9

This comment has been minimized.

Copy link

@shreyashah9 shreyashah9 commented Dec 2, 2014

My onload function is not getting called here and even the image is not getting displayed..please suggest an option

@Bogdan-Catalin

This comment has been minimized.

Copy link

@Bogdan-Catalin Bogdan-Catalin commented Jan 26, 2015

Using this to draw a d3pie pie chart to the canvas just renders an empty object.
However, I can easily append img to a container in the document and it's loaded as a SVG resource with no problems.

Any idea why ?

Edit: Decided to use canvg and pass svgData to it instead of creating an img out of it and it works ! But I still don't understand why the original code didn't work...

@amit-rana

This comment has been minimized.

Copy link

@amit-rana amit-rana commented Feb 16, 2015

converting svg to data url is working but when I try to render it to canvas it's not showing images that used in svg... any idea I have already add required attrs to svg

here is my code

 var html = d3.select("svg")
    .attr({
        'xmlns': 'http://www.w3.org/2000/svg',
        'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink',
        version: '1.1'
    }) 
    .node().parentNode.innerHTML;

  var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);

  d3.select('canvas').attr('width',_canvasWidth).attr('height',_canvasHeight);
  var canvas = document.querySelector("canvas"),
      context = canvas.getContext("2d");

  var image = new Image;
  image.src = imgsrc;
  image.onload = function() {
  context.drawImage(image, 0, 0);

  var canvasdata = canvas.toDataURL("image/png");

  var pngimg = '<img src="'+canvasdata+'">'; 
  d3.select("#pngdataurl").html(pngimg);

  var a = document.createElement("a");
  a.download = "export_"+Date.now()+".png";
  a.href = canvasdata; 
  document.body.appendChild(a);
  a.click();
  };
@maciejjankowski

This comment has been minimized.

Copy link

@maciejjankowski maciejjankowski commented Mar 21, 2015

IE11 (probably others too) have some issues with SVG namespaces - I don't know if it is the Raphael to blame or something else. One solution is to fix the namespaces yourself:

you will have some weird stuff like:

xmlns:NS1="" NS1:xmlns:xlink="http://www.w3.org/1999/xlink"

replace it with:

xmlns:xlink="http://www.w3.org/1999/xlink"

and fix the xlinks accordingly

@lukehorvat

This comment has been minimized.

Copy link

@lukehorvat lukehorvat commented Jun 3, 2015

If your SVG styling isn't inline, you can use this package: https://github.com/lukehorvat/computed-style-to-inline-style

@goosehub

This comment has been minimized.

Copy link

@goosehub goosehub commented Jun 22, 2015

@philfreo , I found your function useful, but it was still partially cut off, so as a hack, I did this to ensure it wasn't cut off. Won't work in all cases. Just a heads up that getBoundingClientRect() doesn't seem to always work.

            canvas.width = svgSize.width * 2;
            canvas.height = svgSize.height * 2;

By the way, this gist is a lifesaver!

@guillemp

This comment has been minimized.

Copy link

@guillemp guillemp commented Oct 29, 2015

Here's what i'm using. Works fine in Chrome but not on Firefox... Any ideas?

function svg_to_png(container) {
    var wrapper = document.getElementById(container);
    var svg = wrapper.querySelector("svg");

    if (typeof window.XMLSerializer != "undefined") {
        var svgData = (new XMLSerializer()).serializeToString(svg);
    } else if (typeof svg.xml != "undefined") {
        var svgData = svg.xml;
    }

    var canvas = document.createElement("canvas");
    var svgSize = svg.getBoundingClientRect();
    canvas.width = svgSize.width;
    canvas.height = svgSize.height;
    var ctx = canvas.getContext("2d");

    var img = document.createElement("img");
    img.setAttribute("src", "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgData))) );

    img.onload = function() {
        ctx.drawImage(img, 0, 0);
        var imgsrc = canvas.toDataURL("image/png");

        var a = document.createElement("a");
        a.download = container+".png";
        a.href = imgsrc;
        a.click();
    };
}
@kyptov

This comment has been minimized.

Copy link

@kyptov kyptov commented Jan 7, 2016

@guillemp
put your img.setAttribute(...) after img.onload

@zhangbg

This comment has been minimized.

Copy link

@zhangbg zhangbg commented Jan 28, 2016

@guillemp
you should append in the body!

document.body.appendChild(a);
@jankovicsandras

This comment has been minimized.

Copy link

@jankovicsandras jankovicsandras commented Feb 24, 2016

@abishekrsrikaanth "Is there a way to convert PNG to SVG?"
Yes, there is now: https://github.com/jankovicsandras/imagetracerjs

@cristo1985

This comment has been minimized.

Copy link

@cristo1985 cristo1985 commented Mar 7, 2016

Hi. How can i convert svgz (compressed svg) from url? Tried with CloudConvert and work properly with svgz!! How can i do using svg2png.js file?
Thanks pls!! We need it!!!

@toastal

This comment has been minimized.

Copy link

@toastal toastal commented Jan 8, 2017

Seems a little odd to base64 encode it.... I went with

var img = new Image()
img.src = "data:image/svg+xml;utf8," + svgData
@maneetgoyal

This comment has been minimized.

Copy link

@maneetgoyal maneetgoyal commented Jun 8, 2017

@toastal Using utf8 didn't seem to work. Did it work for you? I am Using Chrome.

@FALCON-084

This comment has been minimized.

Copy link

@FALCON-084 FALCON-084 commented Dec 16, 2017

var svg = document.querySelector( "svg" );
var svgData = new XMLSerializer().serializeToString( svg );

var canvas = document.createElement( "canvas" );
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
var ctx = canvas.getContext( "2d" );

var img = document.createElement( "img" );
img.setAttribute( "src", "data:image/svg+xml;base64," + btoa( svgData ) );

img.onload = function() {
ctx.drawImage( img, 0, 0 );

// Now is done
console.log( canvas.toDataURL( "image/png" ) );

};

Worked with this code. but for some SVG files it is showing "NETWORK ERROR". Can u help?

@mehulchauhan31

This comment has been minimized.

Copy link

@mehulchauhan31 mehulchauhan31 commented Mar 26, 2018

When I convert SVG to PNG it only export graph plot not graph data to PNG .
Please Advice or suggest any solution.

@NorhanSamir

This comment has been minimized.

Copy link

@NorhanSamir NorhanSamir commented Mar 28, 2018

I'm trying to export angular-d3-charts to PDF as an image but the chart is not complete the x-axis are hidden as it's not inline style is there any workaround to solve this ???

@concatime

This comment has been minimized.

@linnabrown

This comment has been minimized.

Copy link

@linnabrown linnabrown commented Jun 24, 2020

You save my life!!!!!!!!!!!!!!!!!!!! @guillemp This code works well! Thank you very much!

I used snap JS to draw svg, here what I do:

var s = Snap('#svg_id');
var svg = document.querySelector( "#svg_id" );
var svgData = new XMLSerializer().serializeToString( svg );
var canvas = document.createElement( "canvas" );
canvas.width = 1500;
canvas.height = 1450;
var ctx = canvas.getContext( "2d" );
var img = document.createElement( "img" );
img.setAttribute( "src", s.toDataURL());
console.log(s.toDataURL());
img.onload = function() {
	ctx.drawImage( img, 0, 0 );
	console.log( canvas.toDataURL( "image/png" ) );
	var imgsrc = canvas.toDataURL( "image/png" );
	var a = document.getElementById("download_png");
	a.download = "filename.png"
	a.href = imgsrc;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment