我需要将输入图像(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 。< / p>
现在,如果您在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输出极大。
我该如何提高效率?
答案 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...">