javascript - FileReader readAsDataURL 创建大型 base64 图像
问题描述
我需要将输入图像(blob)转换为 base64 图像。我知道大小将增加约 1.37。
但是我注意到,firereader.readAsDataUrl
与 macOS 上的内置 base64 命令行工具相比,使用图像的大小非常大。
https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
重现步骤:
下载此免费示例图片https://wall.alphacoders.com/big.php?i=685897确保单击“下载”按钮(Downlaod Original 8000x600)。不要使用右键另存为,因为图像会被压缩
使用 jsfiddle 选择上面下载的图像并检查控制台日志以获取 base 64 的大小。https://jsfiddle.net/b7nkw8j9/你可以看到大小为11.2mb。
现在,如果您在 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
会使图像base64输出非常大。
我怎样才能使它更有效率?
解决方案
我有 5,882,455 字节用于 FileReader 与 5,882,433 字节用于base64
输出,如果您从 中添加 22 字节data:image/png;base64,
,我们不会太远。
但是对于这个问题,我怎样才能提高效率?,只是不要在这里使用数据 URL。无论你被告知你也需要它,那都是谎言(我有 99% 的把握)。
相反,您应该始终更喜欢直接使用 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/*">
要将其发送到您的服务器,请直接发送 Blob,通过 FormData 或直接从 xhr.send() 或作为获取请求的主体发送。
唯一可以想到在前端需要二进制文件的数据 URL 版本的情况是生成需要嵌入该二进制文件的独立文档。对于我在职业生涯中遇到的所有其他用例,Blob 更适合。
对于在 Chrome 的工具提示中打印的消息,这是浏览器必须在内存中保存的USVString的大小。它是磁盘上文件大小的两倍,因为 USVStrings 是用 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...">
推荐阅读
- ruby - 无法在 Homebrew 上安装 OpenSSL
- google-apps-script - 如何在谷歌表格中取消保护带有代码的按钮?
- java - Java Eclipse:线程“main”中的异常 java.lang.Error 在导入的包中
- c++ - 使用 C++ 移动输入文件
- algorithm - 更精简的算法通过多个标准对结构切片进行分组
- python - 我得到了这个形状 (1,254,254,1) 而预期的形状是 (1,254,254,3)
- java - Spark 独立模式下工作节点上的线程“主”java.lang.reflect.UndeclaredThrowableException 中的异常
- javascript - 总是承诺,但没有结果
- arrays - 如果 struct 中的字符大小为 30 或更大,则程序终止
- groovy - 对 JSON 响应中的数据进行排序以进行比较