Canvas toDataURL()函数完成后执行函数

时间:2017-03-13 16:25:37

标签: javascript canvas callback base64 todataurl

我正在使用canvas将图像转换为base64。我需要做的是转换这些图像,然后将结果显示给用户(原始图像和base64版本)。一切都按预期的方式使用小图像,但是当我尝试转换大图像(> 3MB)并且转换时间增加时,base64版本为空。 这可能是 引起的,因为结果是在toDataURL()函数完成之前显示的。

出于测试目的,我需要在所有需要的处理结束后显示结果。

这是我的代码:

var convertToBase64 = function(url, callback)
{
    var image = new Image();

    image.onload = function ()
    {
        //create canvas and draw image...

        var imageData = canvas.toDataURL('image/png');          
        callback(imageData);
    };

    image.src = url;
};


convertToBase64('img/circle.png', function(imageData)
{
    window.open(imageData);
});

即使我使用带回调的image.onload(),我也无法在处理完toDataURL()后显示结果。

我做错了什么?

更新:我尝试了以下两种解决方案,但它们无效。我在这个项目中使用AngularJS和Electron。 我可以用任何方式强制代码同步吗?或者也许使用Promises的解决方案?

UPDATE#2:@Kaiido指出toDataURL()实际上是同步的,这个问题更可能是由于URI的最大长度。由于我使用Electron并且图像预览仅用于测试目的,我将把文件保存在文件夹中并从那里进行分析。

2 个答案:

答案 0 :(得分:1)

您的代码似乎绝对正常。不知道为什么不工作。也许,您的浏览器存在一些问题。也许尝试使用不同的。您也可以使用custom event,它会在图像转换竞争时触发。

// using jQuery for custom event

function convertToBase64(url) {
    var image = new Image();
    image.src = url;
    image.onload = function() {
        var canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        var ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0);
        var imageData = canvas.toDataURL();
        $(document).trigger('conversionCompleted', imageData);
    };
};

convertToBase64('4mb.jpg');
$(document).on('conversionCompleted', function(e, d) {
    window.open(d);
});

答案 1 :(得分:1)

这种方法可能适合您。它使用本机html元素在屏幕上显示图像,然后将其绘制到画布,然后将画布转换为Base64,然后清除画布并将转换后的图像绘制到画布上。然后,您可以在顶部图像(原始图像)和底部图像(转换)之间滚动。我在大图像上尝试了它,第二张图像需要一两秒才能画出来,但它似乎有用......

Html在这里:

<img id="imageID">
<canvas id="myCanvas" style="width:400;height:400;">
</canvas>

脚本在这里:

var ctx;
function convertToBase64(url, callback)
{
  var image = document.getElementById("imageID");
  image.onload = function() {
    var canvas = document.getElementById("myCanvas");
    canvas.width = image.naturalWidth;
    canvas.height = image.naturalHeight;
    ctx = canvas.getContext("2d");
    ctx.drawImage(image,0,0);
    var imageData = canvas.toDataURL('image/png');
    ctx.fillStyle ="#FFFFFF";
    ctx.fillRect(0,0,canvas.width,canvas.height);
    callback(imageData);
  };
  image.src = url;
};

var imagename = 'images/bigfiletest.jpg';

window.onload = function () {
  convertToBase64(imagename, function(imageData) {
    var myImage = new Image();
    myImage.src = imageData;
    ctx.drawImage(myImage,0,0);    
  });
}

请注意,我在没有回调的情况下尝试了它,它也运行良好......