FileReader readAsDataURL 创建大型 base64 图像
FileReader readAsDataURL creating large base64 images
我需要将输入图像 (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 请确保单击“下载”按钮(下载原始 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 输出非常大。
我怎样才能使它更有效率?
FileReader 有 5,882,455 个字节,base64
输出有 5,882,433 个字节,如果你从 data:image/png;base64,
中添加 22 个字节,我们就不会太远了。
但是对于问题 我怎样才能使它更有效率?,只是不要在这里使用数据 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/*">
要将其发送到您的服务器,send the Blob directly,可以通过 FormData 或直接来自 xhr.send() 或作为获取请求的主体。
唯一可以想到在前端需要数据 URL 版本的二进制文件的情况是生成需要嵌入该二进制文件的独立文档。对于我在职业生涯中遇到的所有其他用例,Blob 更适合。
对于在 Chrome 的工具提示中打印的消息,这是浏览器必须保存在内存中的 USVString 的大小。它是磁盘上文件大小的两倍,因为 USVStrings 是用 UTF-16 编码的,即使这个字符串只包含 ASCII 字符。
但是,要发送到您的服务器,或保存为文本文件,通常会重新编码为 8 位编码,并恢复为正常大小。
所以不要将此工具提示作为告诉您数据有多大的意思,它只是它在浏览器分配的内存中占用的大小,但在外部,它根本不一样。
如果你想检查生成的二进制数据的大小,这里更好fiddle,它会将 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...">
我需要将输入图像 (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 请确保单击“下载”按钮(下载原始 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 输出非常大。
我怎样才能使它更有效率?
FileReader 有 5,882,455 个字节,base64
输出有 5,882,433 个字节,如果你从 data:image/png;base64,
中添加 22 个字节,我们就不会太远了。
但是对于问题 我怎样才能使它更有效率?,只是不要在这里使用数据 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/*">
要将其发送到您的服务器,send the Blob directly,可以通过 FormData 或直接来自 xhr.send() 或作为获取请求的主体。
唯一可以想到在前端需要数据 URL 版本的二进制文件的情况是生成需要嵌入该二进制文件的独立文档。对于我在职业生涯中遇到的所有其他用例,Blob 更适合。
对于在 Chrome 的工具提示中打印的消息,这是浏览器必须保存在内存中的 USVString 的大小。它是磁盘上文件大小的两倍,因为 USVStrings 是用 UTF-16 编码的,即使这个字符串只包含 ASCII 字符。
但是,要发送到您的服务器,或保存为文本文件,通常会重新编码为 8 位编码,并恢复为正常大小。
所以不要将此工具提示作为告诉您数据有多大的意思,它只是它在浏览器分配的内存中占用的大小,但在外部,它根本不一样。
如果你想检查生成的二进制数据的大小,这里更好fiddle,它会将 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...">