Javascript 函数完成后执行函数

Javascript 函数完成后执行函数,javascript,canvas,callback,base64,todataurl,Javascript,Canvas,Callback,Base64,Todataurl,我正在使用画布将图像转换为base64。我需要做的是转换这些图像,然后将结果显示给用户(原始图像和base64版本)。对于小图像,一切正常,但是当我尝试转换大图像(>3MB)并且转换时间增加时,base64版本是空的。 这可能是因为结果是在toDataURL()函数完成之前显示的 为了测试的目的,我需要在所有需要的处理结束后显示结果 这是我的密码: var convertToBase64 = function(url, callback) { var image = new Image(

我正在使用画布将图像转换为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。我能强迫代码同步吗?或者使用承诺的解决方案?


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

您的代码似乎非常好。不知道为什么你不工作。也许,您的浏览器存在一些问题。也许试着用另一个。您还可以使用
自定义事件
,该事件在图像转换完成时触发

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

你的代码看起来非常好。不知道为什么你不工作。也许,您的浏览器存在一些问题。也许试着用另一个。您还可以使用
自定义事件
,该事件在图像转换完成时触发

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

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

Html在这里:

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

请注意,我也在没有回调的情况下尝试了它,效果也不错……

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

Html在这里:

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

请注意,我也在没有回调的情况下尝试了它,效果也很好…

您的image.src行应该位于image.onload的定义之后。似乎有很多帖子都与此相关。其概念是,如果缓存了图像,那么它可以在执行前立即加载,以设置image.onload,因此onload将永远不会触发。这里有一个这样的帖子,但有几个@暹罗谢谢你的建议。我用的是运行在Chrome上的Electron。你的解决方案不起作用,我还有其他选择吗?如果有帮助的话,我正在使用AngularJS…你的image.src行应该在image.onload的定义之后。似乎有很多帖子与此相关。其概念是,如果缓存了图像,那么它可以在执行前立即加载,以设置image.onload,因此onload将永远不会触发。这里有一个这样的帖子,但有几个@暹罗谢谢你的建议。我用的是运行在Chrome上的Electron。你的解决方案不起作用,我还有其他选择吗?我正在使用AngularJS,如果有帮助的话……谢谢你的帮助。不幸的是,你的解决方案也不起作用。我可以尝试其他选择吗?如果有帮助的话,我正在使用AngularJS和Electron。谢谢你的帮助。不幸的是,你的解决方案也不起作用。我可以尝试其他选择吗?如果有帮助的话,我会使用AngularJS和Electron。“这是因为结果是在toDataURL()函数完成之前显示的。”不,
toDataURL
方法是同步的。这很可能是由于位置的最大URI长度,您使用的浏览器是什么?为什么需要base64版本?如果只是在新页面中打开图像,那么选择一个(IE)和方法。谢谢回复。因为这个应用程序是在Electron上运行的,所以我真的必须使用Chrome。我想要dataURL,因为我认为它是查看结果图像的最快方式(用于测试目的)。无论如何,我改变了我的方法,不是在新窗口中显示图像,而是将其保存到一个文件中。没有toDataURL比toBlob慢,并且是同步的(可能会冻结您的屏幕)。toBlob应该总是首选。chrome确实支持toBlob和blobURIs(使用
URL.createObjectURL(blob)
创建),我最初使用这种方法是因为我使用的是小图像,而且一切都可以无缝工作。感谢您提供的提示:)“这是因为结果是在toDataURL()函数完成之前显示的。”否,
toDataURL
方法是同步的。这很可能是由于位置的最大URI长度,您使用的浏览器是什么?为什么需要base64版本?如果只是在新页面中打开图像,那么选择一个(IE)和方法。谢谢回复。因为这个应用程序是在Electron上运行的,所以我真的必须使用Chrome。我想要dataURL,因为我认为它是查看结果图像的最快方式(用于测试目的)。无论如何,我改变了我的方法,不是在新窗口中显示图像,而是将其保存到一个文件中。没有toDataURL比toBlob慢,并且是同步的(可能会冻结您的屏幕)。toBlob应该总是首选。chrome确实支持toBlob和