上下文.多个图像的drawImage最终会导致FireFox崩溃



我正在创建一个图像上传器,应该能够接受至少1000张图像。一旦用户选择/拖放图像,图像应该显示预览的目的。然后,用户将点击上传按钮开始上传。

我已经实现了整个功能,它在Chrome上的工作就像一个魅力。但这在Firefox中失败了。

我已经创建了一个排队机制,这样在一个时间点上,只有n个图像将被加载到浏览器中,一旦用户选择了图像。

对于超过20个图像也会发生崩溃(即使使用排队机制创建一批1个图像)。我在Firefox中使用Tab memory usage Plugin(http://mybrowseraddon.com/tab-memory.html)检查了内存使用情况。它甚至崩溃的内存利用率为40 MB。所以我猜,这不是因为任何内存泄漏。

function readAndDisplay(file, index){
    id = getFileId(file);
    reader = new FileReader();
    reader.onload = function (e) {
        addImageCard(file, index);
        resizeImage(e, index);
        delete this;
        //$('#image' + id).attr('src', e.target.result);
    }
    reader.readAsDataURL(file);
}
function resizeImage(fileReaderEvent, index){
    var img = new Image();
    img.onload=function(){
        var MAX_WIDTH = 800;
        var MAX_HEIGHT = 600;
        var width = img.width;
        var height = img.height;
        if (width > height) {
          if (width > MAX_WIDTH) {
            height *= MAX_WIDTH / width;
            width = MAX_WIDTH;
          }
        } else {
          if (height > MAX_HEIGHT) {
            width *= MAX_HEIGHT / height;
            height = MAX_HEIGHT;
          }
        }
        var canvas = document.getElementById("image" + index);
        var ctx = canvas.getContext("2d");
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(img, 0, 0, width, height);
        img.src = "";
        delete canvas;
        delete ctx;
        img = null;
        delete fileReaderEvent;
        uploadQueue.push(index);
        if(loadImageIterator < updatedFiles.length){
            loadImage(updatedFiles[loadImageIterator++]);
        }
        else{
            updatedFiles = [];
        }
    }
    img.src = fileReaderEvent.target.result;
    var md5 = CryptoJS.MD5(fileReaderEvent.target.result).toString();
    console.log(md5);
}
function addImageCard(file, index){
    imageHolder = $("#imageholder");
    imageCard = $("<div>", {
        class: "col m1 s4",
        id: "card" + index
    });
    innerDiv = $("<div>", {
        class: "card"
    });
    cardImage = $("<div>", {
        class: "card-image",
    }).append($("<canvas>", {
        id: "image" + index,
        css: {
            width: "100%"
        }
        //src: "images/sample-1.jpg"
    })).append($("<span>", {
        class: "card-title",
        text: ""
    }));
    cardContent = $("<div>",{
        class: "card-content",
        html: "<p>" + file.name + "</p>"
    });
    cardAction = $("<div>", {
        class: "card-action"
    });
    removeButton = $("<a>", {
        title: "Remove",
        css: {
            "font-size": "20px"
        },
        click: function(){
            remove(index)
        }
    }).append($("<span>", {
        class: "glyphicon glyphicon-remove-circle"
    }));
    uploadButton = $("<a>", {
        title: "Upload Now",
        css: {
            "font-size": "20px",
            float: "right",
            "margin-right": "4px"
        }
    }).append($("<span>", {
        class: "glyphicon glyphicon-cloud-upload"
    }));
    cardAction.append(removeButton);
    cardAction.append(uploadButton);
    innerDiv.append(cardImage);
    innerDiv.append(cardContent);
    innerDiv.append(cardAction);
    imageCard.append(innerDiv);
    imageHolder.append(imageCard);
}

当我注释下面的代码时,Firefox不会崩溃ctx。drawImage(img, 0,0, width, height)

所以我认为到目前为止,这个问题是与这个drawImage。可能drawImage的实现在Chrome和Firefox中是不同的,我使用它的方式使它在Chrome中工作,但在Firefox中,它会抛出一个错误。

有没有人对这个问题发生的原因有具体的想法?

JSFiddle——http://jsfiddle.net/sanchit235/7xh1gbj6/

Firefox崩溃报告- https://crash-stats.mozilla.com/report/index/6107c530-12a1-4aea-96c9-0366c2151010

你的代码有几个问题:

  • 第一个是你在FileSelectHandler() (onchange)的for循环中同步调用loadImage(),如果循环没有完成,一旦绘图完成,它本身就会异步调用loadImage()(在我的比较中,它在20张图片中发生了15次)。

  • 只需在更改时调用它一次并允许异步回调就足够了。
  • 第二个是在检查回调:
    if(loadImageIterator < updatedFiles.length){ loadImage(updatedFiles[loadImageIterator++]); }
    应该用
    代替if(++loadImageIterator < updatedFiles.length){ loadImage(updatedFiles[loadImageIterator]); }

  • 第三个是变量声明。你在reader, newFile和其他一些var之前忘记了CC_7,使它们成为全局变量。

这是更正后的小提琴,不会抛出任何错误在Chrome或FF,无需删除任何自己。

最新更新