使用FileAPI减少读取映像的内存和CPU使用率

时间:2012-09-20 10:19:51

标签: javascript canvas fileapi

所以我正在使用这个功能来读取用户硬盘中的图像,如果它们的浏览器能够使用FileAPI,则将它们显示为缩略图:

// loop over them sequentially to prevent hogging memory
function load(i) {
    reader.onload = (function(file) {
        return function(e) {
            var loadNext = function(i) {
                if (data[i + 1] !== undefined) {
                    setTimeout(function() {
                        load(i + 1);
                    }, 100);
                }
            };

            if (e.target.result.match(/^data\:image\/.*$/) === null) {
                loadNext(i);
                return;
            }

            // output file name
            placeholders[i].custom.children.title.html(file.name);

            // the server has returned an error, don't load the image
            if (placeholders[i].custom.error === true) {
                placeholders[i].custom.update({loaded: true});
                loadNext(i);
                return;
            }

            // create new image
            var $image = $('<img />')
                .attr('alt', '')
                .attr('src', e.target.result)
                .attr('title', file.name);

            // setup remove link
            placeholders[i].custom.children.remove
                .click(function(event) {event.preventDefault();})
                .attr('data-file-name', file.name);

            // once finished loading
            $image.load(function() {
                if (placeholders[i].custom.error !== true) {
                    placeholders[i].addClass('success').attr('id', 'preview-' + file.name)
                    placeholders[i].custom.children.content.html($image);
                }
                placeholders[i].custom.update({loaded: true});

                loadNext(i);
            });
            return;
        }
    })(data[i]);

    reader.readAsDataURL(data[i]);
}
load(0);

问题是如果他们上传一个特别大的文件或大量的文件,那么CPU使用率(以铬计)和内存使用量(在firefox中)往往会上升。

我刚才解决了这个问题(我不得不停止这个项目并回到它)我设法通过确保文件(来自<input type="file" multiple="multiple" />元素)来解决一些问题按顺序加载。不幸的是,这还不够,所以我开始尝试以块的形式加载数据,并在读取每个块(slice和readAsArrayBuffer)时添加了一个短暂的延迟,这解决了大部分读取问题。

如何将数据缓冲区中的数据输出到画布?我最后一次显示了一些东西,但它被争夺得无法辨认。

1 个答案:

答案 0 :(得分:0)

http://jsfiddle.net/8A3tP/1/

以下是我最终如何做到这一点。我使用window.btoa()将二进制数据(使用readAsBinaryString而不是readAsArrayBuffer)转换为base64字符串。从那里我可以使用var image = document.createElement('img'); image.src = result;创建一个图像对象,并使用它来使用Canvas2DContext.drawImage(image,0,0)填充画布;