I'm trying to convert svg to png images using phantomjs:
var page = require('webpage').create();
page.evaluate(function() {
var svg = '<svg class="tnt_tracks_svg" width="800" height="180" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/\
xlink"><rect width="10" height="10" fill="red"></rect></svg>';
var src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svg)));
var img = new Image();
img.src = src;
img.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
var src = canvas.toDataURL(); // DOM Exception 18!
}
});
But I'm getting a DOM Exception 18 when calling toDataURL. I have seen in other similar questions that this may happen if the svg is hosted in other domains etc..., but in my case I'm providing the svg src!. What is wrong with the code above? Why is it firing the DOM Exception?
A similar code looks good in jsfiddle (no phantomjs, tested in chrome and FF). And this phantom example is also working using fabric.js:
page.includeJs("http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js", function () {
page.evaluate(function() {
var svg_text = '<svg width="600" height="400"><g><rect width="10" height="10" fill="red"></rect></g></svg>';
fabric.loadSVGFromString(svg_text, function (objects, options) {
var loadedObject = fabric.util.groupSVGElements(objects, options);
var canvas = new fabric.Canvas('canvas');
canvas.add(loadedObject);
canvas.calcOffset();
canvas.renderAll();
console.log (canvas.toDataURL('png'));
});
});
});
I'm trying to find the relevant code in fabric.js, but any help would be much appreciated.
Ok, answering my question after some research...
It looks like webkit is always setting the origin-clean flag to false every time a data-uri string is set as source attribute of a HTML image, which is then rendered on Canvas element. Firefox and Chrome (for example), allow this for some cases, but not webkit.
Fabric.js doesn't suffer from this problem because it renders the shapes into canvas but don't use the data uri for that, so the canvas is not tainted.
Another solution is to use canvg and SVG.toDataURL.
References here:
Issue explained: http://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/#security_issues
Webkit issues: Several, see for example this and this
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