I'm trying to convert a large SVG (it's data URL is about 750000 - 1000000 characters) to a PNG by passing it's data url through an image and into a canvas but the image is only loading about 1/4 of the SVG.
Creating via:
var svg_xml = (new XMLSerializer()).serializeToString(svg),
url = 'data:image/svg+xml;base64,' + btoa(svg_xml);
var img = new Image();
img.width = 730;
img.height = 300;
img.onload = function(){
var canvas = document.create('canvas');
canvas.width = 730;
canvas.height = 300;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, 730, 300);
callbackFn(canvas.toDataURL('image/png');
}
img.src = url
Edit
I've tried implementing canvg to draw the SVG but the DataURL produced results in a blank image:
var svg_xml = (new XMLSerializer()).serializeToString(svg);
var canvas = document.createElement('canvas');
canvas.width = 730;
canvas.height = 300;
var ctx = canvas.getContext('2d');
ctx.drawSvg(svg_xml, 0, 0, 730, 300);
callbackFn(canvas.toDataURL('image/png');
Is there anything wrong with the method I've used?
Further Edit
I'm now fairly convinced that it's the canvas failing to draw the whole image as I tried implementing a Blob solution to the same effect:
var svg_xml = (new XMLSerializer()).serializeToString(svg),
blob = new Blob([svg_xml], {type:'image/svg+xml;charset=utf-8'}),
url = window.URL.createObjectURL(blob);
var img = new Image();
img.width = 730;
img.height = 300;
img.onload = function(){
var canvas = document.create('canvas');
canvas.width = 730;
canvas.height = 300;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, 730, 300);
window.URL.revokeObjectURL(url);
callbackFn(canvas.toDataURL('image/png');
}
img.src = url
The image again loads fine and going to the URL (before it's revoked) displays the image fine as well.
The length of the canvas dataURL is not consistent so I don't think that's maxing out, is there a way of detecting the canvas size? The application is only supported for Chrome and FireFox.
SVG to PNG – Convert SVG files to PNG Online Use this free online SVG to PNG converter to convert SVG files to PNG images, quickly and easily, without having to install any software. Click the UPLOAD FILES button and select up to 20 SVG files you wish to convert.
You can also click to select SVG files using your operating system's file picker. Another method is to press the keyboard shortcut Ctrl+V (⌘+V on Mac) to paste an SVG file you have copied to clipboard. Converting a folder with SVG files to PNG is also supported: simply paste or drag and drop it.
Portable Network Graphics (PNG) is a raster-based file type that compresses images for portability. PNG images can have RGB or RGBA colors and support transparency, which makes them perfect for use in icons, or graphic designs. PNG also supports animations with better transparency (try our GIF to APNG ).
What is an SVG (Scalable Vector Graphics) file? Scalable Vector Graphics (SVG) is a resolution-independent, open-standard file format. It is based on Extensible Markup Language ( XML ), uses vector graphics, and supports limited animation.
Working fiddle.
HTML:
<div>
<svg xmlns="http://www.w3.org/2000/svg"
width="526" height="233">
<rect x="13" y="14" width="500" height="200" rx="50" ry="100"
fill="none" stroke="blue" stroke-width="10" />
</svg>
<a id='imgId'>Save</a>
</div>
<canvas></canvas>
JavaScript:
var svg = document.getElementsByTagName('svg')[0];
var svg_xml = (new XMLSerializer()).serializeToString(svg),
blob = new Blob([svg_xml], {type:'image/svg+xml;charset=utf-8'}),
url = window.URL.createObjectURL(blob);
var img = new Image();
img.width = 730;
img.height = 300;
img.onload = function(){
var canvas = document.createElement('canvas');
canvas.width = 730;
canvas.height = 300;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, 730, 300);
window.URL.revokeObjectURL(url);
var canvasdata = canvas.toDataURL('image/png');
var a = document.getElementById('imgId');
a.download = "export_" + Date.now() + ".png";
a.href=canvasdata;
}
img.src = url
Your question:
Why image is only loading about 1/4 of the SVG?
Answer:
Just follow these rules:
x
of <rect/>
+ width
of <rect/>
<= width
of <svg/>
y
of <rect/>
+ height
of <rect/>
<= height
of <svg/>
For example:
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="200">
<rect x="10" y="10" width="550" height="250" rx="50" ry="100"
fill="none" stroke="blue" stroke-width="10" />
</svg>
Here, x
of <rect/>
= 10
, width of <rect/>
= 550
, width of <svg>
= 500
so, 10
+550
>500
In this case image will be partially rendered.
Hope this will solve your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With