-
-
Save gustavohenke/9073132 to your computer and use it in GitHub Desktop.
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" ) ); | |
}; |
Not that I'm aware of.
PNG is a raster image type, while SVG is a vector.
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
.
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;
My onload function is not getting called here and even the image is not getting displayed..please suggest an option
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...
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();
};
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
If your SVG styling isn't inline, you can use this package: https://github.com/lukehorvat/computed-style-to-inline-style
@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!
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();
};
}
@Guillemp
put your img.setAttribute(...) after img.onload
@Guillemp
you should append in the body!
document.body.appendChild(a);
@abishekrsrikaanth "Is there a way to convert PNG to SVG?"
Yes, there is now: https://github.com/jankovicsandras/imagetracerjs
Seems a little odd to base64 encode it.... I went with
var img = new Image()
img.src = "data:image/svg+xml;utf8," + svgData
@toastal Using utf8 didn't seem to work. Did it work for you? I am Using Chrome.
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?
When I convert SVG to PNG it only export graph plot not graph data to PNG .
Please Advice or suggest any solution.
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 ???
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;
};
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(); }; }
Thanks
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?
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(); }; }
worked for me, thanks
sorry can somebody tell me what is container hier ? image Tag?
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();
};
}
Is there a way to convert PNG to SVG?