使用 readAsDataURL 加载选定图像时,HTML5 文件 API 使 Chrome 崩溃

发布于 2024-11-13 01:17:46 字数 756 浏览 3 评论 0原文

这是我的示例代码:

var input = document.createElement('input');
input.type = 'file';
document.body.appendChild(input);

input.addEventListener('change', function(){
    var file = input.files[0];

    var reader = new FileReader();
    reader.onload = function(e){
        var image = new Image();
        image.src = e.target.result;
    };
    reader.readAsDataURL(file);
});

加载页面,选择一个大图像(我使用的是 2.9MB 4288x3216 图像)。刷新页面并选择相同的图像。结果?选项卡崩溃了! (噢,啪!)

我的猜测是,这是 Chrome 的文件 API 实现中的一个错误,但如果有人能够确认这一点,甚至可能提供解决方法,我会很高兴。我真的希望能够显示照片的缩略图,而不必去服务器生成缩略图(即使它仅适用于 Chrome 和 FF)。

另外,根据上面的示例代码,一旦您选择照片,该选项卡就会开始使用大约 32MB 的内存。我想,这是预料之中的,但令我担心的是,垃圾收集器似乎永远不会释放内存。因此,如果我继续选择更多照片,我就会继续消耗更多内存。我不知道这是否与崩溃问题有关,但这绝对是一个问题。

感谢您的帮助!

Here's my sample code:

var input = document.createElement('input');
input.type = 'file';
document.body.appendChild(input);

input.addEventListener('change', function(){
    var file = input.files[0];

    var reader = new FileReader();
    reader.onload = function(e){
        var image = new Image();
        image.src = e.target.result;
    };
    reader.readAsDataURL(file);
});

Load the page, select a large image (I'm using a 2.9MB 4288x3216 image). Refresh the page and select the same image. Result? The tab crashes! (Aw, Snap!)

My guess is that this is a bug with Chrome's implementation of the File API, but I'd love it if someone could confirm that and maybe even offer a workaround. I really want to be able to show a thumbnail of a photo without having to go to the server to generate one (even if it's just for Chrome and FF).

Also, with my sample code above, as soon as you select the photo, the tab starts using about 32MB more of memory. That, I guess, is expected, but what concerns me is that the memory never seems to get freed by the garbage collector. So if I keep selecting more photos, I keep consuming more memory. I don't know if this is related to the crashing issue or not, but it's definitely a concern.

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初吻给了烟 2024-11-20 01:17:46

内存问题可能是由以下错误引起的:http://crbug.com/36142。本质上,Chrome 会缓存 data: URL,并且当前在 img.src 更改时不会释放内存。另一个问题是 data: URL 会给您正在编码的数据带来 33% 的开销。这意味着您实际上在图像上设置了约 3.85MB 的资源,而不是 2.9MB。

由于您没有操作内容(实际字节),因此无需读取文件内容。一种选择是创建 blob: url。还有一个显式撤销方法,因此您不会遇到相同的内存缓存问题。像这样的东西:

input.addEventListener('change', function(e) {
  var file = input.files[0];

  window.URL = window.webkitURL || window.URL; // Vendor prefixed in Chrome.

  var img = document.createElement('img');
  img.onload = function(e) {
    window.URL.revokeObjectURL(img.src); // Clean up after yourself.
  };
  img.src = window.URL.createObjectURL(file);
  document.body.appendChild(img);
});

The memory issue could be a result of this bug: http://crbug.com/36142. Essentially, Chrome is caches data: URLs and currently does not release the memory when the img.src is changed. The other issue is that data: URLs yield a 33% overhead to the data you're encoding. That means you're actually setting a ~3.85MB resource on the image, not 2.9MB.

Since you're not manipulating the content (the actual bytes), there's no need to read the file content. One option is to create a blob: url. There's also an explicit revoke method, so you won't run into the same memory caching issues. Something like:

input.addEventListener('change', function(e) {
  var file = input.files[0];

  window.URL = window.webkitURL || window.URL; // Vendor prefixed in Chrome.

  var img = document.createElement('img');
  img.onload = function(e) {
    window.URL.revokeObjectURL(img.src); // Clean up after yourself.
  };
  img.src = window.URL.createObjectURL(file);
  document.body.appendChild(img);
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文