-
-
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" ) ); | |
}; |
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();
};
}
My onload function is not getting called here and even the image is not getting displayed..please suggest an option