简体   繁体   English

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

[英]Execute Function After Canvas toDataURL() Function is Complete

I'm converting images to base64 using canvas. 我正在使用画布将图像转换为base64。 What i need to do is convert those images and then show the result to the user (original image and base64 version). 我需要做的是转换这些图像,然后将结果显示给用户(原始图像和base64版本)。 Everything works as expected with small images, but when i try to convert large images (>3MB) and the conversion time increases, the base64 version is empty. 小图像可以正常工作,但是当我尝试转换大图像(> 3MB)且转换时间增加时,base64版本为空。 This might be is caused because the result is shown before the toDataURL() function is completed. 这可能由于在toDataURL()函数完成之前显示结果而引起的。

I need to show the result after all the needed processing has ended, for testing purposes. 为了测试目的,我需要在所有必要的处理结束后显示结果。

Here's my code: 这是我的代码:

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);
});

Even though i'm using image.onload() with a callback, i'm unable to show the result after the toDataURL() has been processed. 即使我将image.onload()与回调一起使用,在处理toDataURL()之后,我也无法显示结果。

What am i doing wrong? 我究竟做错了什么?

UPDATE: I tried both the solutions below and they didn't work. 更新:我尝试了以下两种解决方案,但它们均无效。 I'm using AngularJS and Electron in this project. 我在这个项目中使用AngularJS和Electron。 Any way i can force the code to be synchronous? 有什么办法可以强制代码同步吗? Or maybe some solution using Promises? 还是一些使用Promises的解决方案?

UPDATE #2: @Kaiido pointed out that toDataURL() is in fact synchronous and this issue is more likely due to maximum URI length. 更新#2:@Kaiido指出toDataURL()实际上是同步的,由于最大URI长度,此问题更有可能发生。 Since i'm using Electron and the image preview was for testing purposes only, i'm going to save the file in a folder and analise it from there. 由于我正在使用Electron,并且图像预览仅用于测试目的,因此我将文件保存在文件夹中并从那里进行分析。

Your code seems absolutely fine. 您的代码似乎绝对正确。 Not sure why isn't working you. 不知道为什么不起作用。 Maybe, there are some issues with your browser. 也许您的浏览器存在一些问题。 Perhaps try using a different one. 也许尝试使用另一种。 Also you could use a custom event , which gets triggered when the image conversion is competed. 您也可以使用custom event ,该竞争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);
});

This approach might work for you. 这种方法可能适合您。 It shows the image onscreen using the native html element, then draws it to a canvas, then converts the canvas to Base64, then clears the canvas and draws the converted image onto the canvas. 它使用本机html元素在屏幕上显示图像,然后将其绘制到画布上,然后将画布转换为Base64,然后清除画布并将转换后的图像绘制到画布上。 You can then scroll between the top image (original) and the bottom image (converted). 然后,您可以在顶部图像(原始)和底部图像(转换)之间滚动。 I tried it on large images and it takes a second or two for the second image to draw but it seems to work... 我在大图像上尝试过,第二个图像需要一两秒钟才能绘制出来,但它似乎可以工作...

Html is here: HTML在这里:

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

Script is here: 脚本在这里:

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);    
  });
}

Note that I also tried it without the callback and it worked fine as well... 请注意,我也尝试了没有回调的情况,并且效果也很好...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM