FileReader readAsDataURL创建大型base64图像

时间:2019-07-04 15:01:04

标签: javascript base64 filereader

我需要将输入图像(blob)转换为base64图像。我知道大小会增加大约1.37。

但是我发现使用firereader.readAsDataUrl时,图像的大小与macOS上内置的base64命令行工具相比非常大。

https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL

复制步骤:

  1. 下载此免费示例图像https://wall.alphacoders.com/big.php?i=685897,请确保单击“下载”按钮(Downlaod Original 8000x600)。不要使用右键单击另存为,因为图像将被压缩

  2. 使用jsfiddle选择上面下载的图像,并检查控制台日志中base 64的大小。https://jsfiddle.net/b7nkw8j9/您可以看到大小为 11.2mb 。< / p>

  3. 现在,如果您在Mac上使用base64命令行工具将上面下载的图像转换为base64,并在那里检查文件大小。您将看到这里的base64大小。 5.9mb base64 -w 0 downloaded_image.jpg > downloaded_image.base64

这是我在代码中使用的将输入文件图像转换为base64的功能。

async convertToBase64(file) {

  if (file === undefined) {
    throw new Error("File could not be found");
  }

  const fileReader = new FileReader();

  return new Promise((resolve, reject) => {
    fileReader.readAsDataURL(file);

    fileReader.onerror = (error) => {
      reject("Input: File could not be read:" + error);
    };

    fileReader.onloadend = () => {
      resolve(fileReader.result);
    };
  });

}

为什么filereader.readAsDataURL使imagebase64输出极大。

我该如何提高效率?

enter image description here

1 个答案:

答案 0 :(得分:1)

对于FileReader,我有5,882,455字节,而对于base64输出,则有5,882,433字节,如果您从data:image/png;base64,中添加22字节,则距离还不算太远。

但是问题我如何使它更有效?,只是不要在此处使用数据URL。无论您是否被告知也需要它,这都是一个谎言(我确信百分之九十九)。

相反,您应该始终喜欢直接使用Blob。

要显示它,请使用Blob URL:

inp.onchange = e => {
  img.src = URL.createObjectURL(inp.files[0]);
};
<input type="file" id="inp">
<img id="img" src="" height="200" alt="Image preview..." accept="image/*">

要通过FormData或直接从xhr.send()或作为获取请求的正文将其发送到服务器,send the Blob directly

唯一可以想到的是,您在前端需要二进制文件的数据URL版本的地方是生成一个独立的文档,该文档需要嵌入该二进制文件。对于我职业生涯中遇到的所有其他用例,Blob都更适合。


对于在Chrome的工具提示中打印的消息,它是浏览器必须保留在内存中的USVString的大小。它是磁盘上文件大小的两倍,因为USVString是用UTF-16编码的,即使该字符串仅包含ASCII字符。
但是,要发送到您的服务器或另存为文本文件,通常会将其重新编码为8位编码,然后恢复其正常大小。

因此,请勿将此工具提示当作告诉您数据有多大的手段,它只是在浏览器分配的内存中占用的大小,而在外部,则根本不一样。

如果您想检查生成的二进制数据的大小,这是一个更好的选择,它将把USVStrings转换为UTF-8并将二进制保持为二进制(例如,如果将ArrayBuffer传递给它):

function previewFile() {
  var preview = document.querySelector('img');
  var file    = document.querySelector('input[type=file]').files[0];
  var reader  = new FileReader();

  reader.addEventListener("load", function () {
    console.log(new Blob([reader.result]).size);
    preview.src = reader.result;
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL -->

<input type="file" onchange="previewFile()"><br>
<img src="" height="200" alt="Image preview...">