Firefox : canvas.toDataURL in image.onload but returning transparent image

梦想的初衷 提交于 2020-01-11 12:52:11

问题


I know that the image must be complete, its loading finished before using the toDataURL function on the canvas, put the code in the image.onload function ensures that.

Also have tried {preserveDrawingBuffer : true} in canvas.getContext.

This is not working in Firefox but works in Chrome...

My code :

var imageWidth = imageHeight = 45;
var image = new Image();

console.log(image);

image.onload = (function (imageWidth, imageHeight) {
    var canvas = document.createElement('canvas');

    d3.select(canvas)
    .attr('width', imageWidth + "px")
    .attr('height', imageHeight + "px");

    var context = canvas.getContext('2d', {preserveDrawingBuffer : true});
    context.drawImage(image, 0, 0, imageWidth, imageHeight);

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

    callback(dataURL);

}).bind(this, imageWidth, imageHeight);

image.onerror =
image.onabort = function () {
    console.error("generateIcon : error on image");
}

image.src = 'data:image/svg+xml;base64,' + btoa(encodeURIComponent(xmlSource).replace(/%([0-9A-F]{2})/g, function (match, p1) {
            return String.fromCharCode('0x' + p1);
        }));

Using xmlSource = "<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54.4 54.4"><g><circle cx="27.2" cy="27.2" r="21.2" stroke-width="3" stroke="#606060" style="fill: rgb(189, 189, 189);"/><text dx="26" dy="34" text-anchor="middle" style="font-size:18px; fill: #000000; font-family: Arial, Verdana; font-weight: bold">90</text></g></svg>"

The resulting dataURL is:

  • Firefox :

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAHElEQVRYhe3BgQAAAADDoPlTH+ECVQEAAAAAxwATRwABzzGAqwAAAABJRU5ErkJggg==

  • Chrome :

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAD20lEQVRYR9VX3ytkURz/3BcS2c2LF+yiPChm1gMhBskLaUbiSXv3L9jdPIp2KXnCAx687JkkJVnlV36U8cAjRpESES8eaHfjRelun9O907hz57pjxma/pRlnzjn3cz/fz/dzvkfBKwrlFWHB/w1GVVU3gI8A+FljwWwAwB4AvxCCn47DMTOqqvLBPwC8N++emZmJq6srq4cSzFchBAE+GU+CUVX1LYCfBgupqanIz89HdnY2MjIyIh5wc3ODi4sLnJyc4O7uzvidYHxCiF92iGzB6CkhG26CcLlcEojTIKBgMGiAIkuf7FIXFYwOhG/0hmmoqalBUlKSUxyheff39wgEAkYaf5PhaIAsweip2aU+8vLyUFlZGTMI84KtrS2cnp5ymAzVWqUsGhgy4qEuyEiiYnV11WAoIISoNe8bAUavmg1qpKmp6VmpiQaeKVtYWDA0RHYeVZkVmDMA7yoqKmISq1P2KOrt7W2ZLiHEh/B1j8Doot0lKy0tLU73j3ne7Oyswc6HcDGbwQwD+FxcXCzL2ByapmFvbw9+vx/n5+fwer1oa2tDSkoKDg8PMT4+Lv2lubkZ7e3tSE9PtwTKct/f3+dv34UQ34xJZjBSuI2NjZaGRjPr6+uTAEpKSjA8PAy32y1FPjQ0hNLSUlRVVWFwcBBFRUVobW2FokTWCI1xcXGRGDaFEKEKMYPROKOjo8PyjTY2NjA5OYmenh7k5ORgZmYGBwcHUuj9/f0SaGFhISYmJmQZd3Z2Ii0tzXIvzmEIIUIY4gIzPz+PtbU1eDwerKysoLu7Wx4TxnhXVxdomFbhCAwXNzQ0WG5wdnaG3t5eqYfy8nKMjY1JBurr67G+vh4Cw+/T09Oh/602Mzzn2cxQwHRSIYTcPzc3F9fX11Iny8vLiWfGTjPmN2Q6dnZ2XkwzttV0eXkpq6aurg7V1dUYHR0FbaCsrAwDAwNyjH8jIyMoKCiIu5psfebh4QFLS0uYmpqSJLF0aQPJyck4Pj6WPnN0dJQwn2Eructy9Pl8MTur0wWOHJibqarKI971D86moBCCLx+KqKc22WEKntNQRWOIpzad9/b2llOePrV1dqSQ7TzHaUrC54X1M4+OAcuzyRjUOz0CcrHnZcrijbBOL6i3nhHNuW0PrGnapqIo6YnqgTVN+6MoiiemHjiMIQqMduuihugpsd4O2CroGiEj6rNuB6aUzVFDHCMoAsrKyop6b6I5sq/RQXDZJgBvXPemcJ3ovTFNMaLrsrlRko0vCbtRmoWrt6Ze/YYp2TIFWaD4517srh1vNTlZ/+Rd28kmiZrzqsD8BVO+9jOAAiWjAAAAAElFTkSuQmCC

Any idea ?

Thanks, mpe


回答1:


You need to set absolute width and height attributes to your root svg node (e.g in px).
The default is 100% but FF has no way to know relative to what (specs don't say yet). ` Chrome makes it relative to something that only they know.

So FF won't draw your svg image, on the canvas, but won't fire an error either, since the image has loaded correctly (in an html document, they could know what the dimensions should be relative to).

var xmlSource = '<svg xmlns="http://www.w3.org/2000/svg" width="45" height="45" viewBox="0 0 54.4 54.4"><g><circle cx="27.2" cy="27.2" r="21.2" stroke-width="3" stroke="#606060" style="fill: rgb(189, 189, 189);"/><text dx="26" dy="34" text-anchor="middle" style="font-size:18px; fill: #000000; font-family: Arial, Verdana; font-weight: bold">90</text></g></svg>';
function callback(dataURI){
  var img = new Image();
  img.src = dataURI;
  document.body.appendChild(img);
  console.log(dataURI);
  }
var imageWidth = imageHeight = 45;
var image = new Image();

image.onload = (function (imageWidth, imageHeight) {
    var canvas = document.createElement('canvas');
    canvas.width = imageWidth;
    canvas.height = imageHeight;
    
    var context = canvas.getContext('2d', {preserveDrawingBuffer : true});
    context.drawImage(image, 0, 0, imageWidth, imageHeight);

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

    callback(dataURL);

}).bind(this, imageWidth, imageHeight);

image.onerror =
image.onabort = function () {
    console.error("generateIcon : error on image");
}

image.src = 'data:image/svg+xml;base64,' + btoa(encodeURIComponent(xmlSource).replace(/%([0-9A-F]{2})/g, function (match, p1) {
            return String.fromCharCode('0x' + p1);
        }));


来源:https://stackoverflow.com/questions/42528266/firefox-canvas-todataurl-in-image-onload-but-returning-transparent-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!