我正在尝试将本地镜像加载为缩略图,如说明的那样 here .我的代码如下。
这适用于小图像。但是,当您尝试加载较大的图像(例如 4mb)时,会出现巨大的滞后。有什么办法可以优化这个吗?
谢谢
HTML
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
Javascript
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
最佳答案
当您在主 UI 线程中运行涉及处理巨大 blob 中的非流式数据的内容时,总会出现延迟。延迟不是来自读取数据,而是在浏览器 UI 中解码和显示图像,因为这涉及同步 UI 操作在 CPU 和 GPU 内存中插入大像素阵列。这是因为 <img>
在实际图像数据大小(宽度 * 高度)的 block 中分配和移动内存,这对于大图像来说是非常大的数量,并且不必要将其推送到 GPU 以仅在屏幕上显示它(导致几毫秒的延迟) .
您很可能可以通过在阅读图像时将图像缩小到可显示的大小来优化您的用例
使用纯 Javascript JPEG 解码器,其中主事件循环以 block 的形式读取文件并将 block 发送到 WebWorker 后台线程进行解码。一个示例解码器库 https://github.com/notmasteryet/jpgjs/blob/master/jpg.js
分配一个
<canvas>
WebWorker 逐步返回生成的像素的元素。此 Canvas 元素不需要匹配实际图像大小(见下文)您还可以在使用纯 Javascript 读取图像时缩小 WebWorker 中的图像 http://www.grantgalitz.org/image_resize/ - 减少将像素推送到 GPU 的需要,因为您首先不会将大图像作为 1:1 像素映射放在显示器上
WebWorker 和主线程可以使用无副本可传输对象推送数据 https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers#Passing_data_by_transferring_.C2.A0ownership_%28transferable_objects%29
然而,尽管此处描述的解决方案近乎完美,但要实现这一解决方案需要具备高级 Javascript 技能,并且该解决方案不会与旧版兼容(阅读:Microsoft)。
关于javascript - 通过 HTML5 filereader 在本地读取大图像作为缩略图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13905578/