Javascript 使用 base64 编码/解码图像破坏图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14967647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 18:30:03  来源:igfitidea点击:

encode/decode image with base64 breaks image

javascriptfileapi

提问by sissonb

I am trying to encode and decode an image. I am using the FileReader's readAsDataURL method to convert the image to base64. Then to convert it back I have tried using readAsBinaryString()and atob()with no luck. Is there another way to persist images without base64 encoding them?

我正在尝试对图像进行编码和解码。我正在使用 FileReader 的 readAsDataURL 方法将图像转换为 base64。然后将其转换回我已经尝试使用 readAsBinaryString()atob()没有运气。有没有另一种方法可以在不使用 base64 编码的情况下保留图像?

readAsBinaryString()

Starts reading the contents of the specified Blob, which may be a File. When the read operation is finished, the readyState will become DONE, and the onloadend callback, if any, will be called. At that time, the result attribute contains the raw binary data from the file.

readAsBinaryString()

开始读取指定 Blob 的内容,它可能是一个文件。当读取操作完成时,readyState 将变为 DONE,并且将调用 onloadend 回调(如果有)。那时,结果属性包含来自文件的原始二进制数据。

Any idea what I'm doing wrong here?

知道我在这里做错了什么吗?

Sample Codehttp://jsfiddle.net/qL86Z/3/

示例代码http://jsfiddle.net/qL86Z/3/

$("#base64Button").on("click", function () {
    var file = $("#base64File")[0].files[0]
    var reader = new FileReader();

    // callback for readAsDataURL
    reader.onload = function (encodedFile) {
        console.log("reader.onload");
        var base64Image = encodedFile.srcElement.result.split("data:image/jpeg;base64,")[1];
        var blob = new Blob([base64Image],{type:"image/jpeg"});
        var reader2 = new FileReader();

        // callback for readAsBinaryString
        reader2.onloadend = function(decoded) {
            console.log("reader2.onloadend");
            console.log(decoded); // this should contain binary format of the image

            // console.log(URL.createObjectURL(decoded.binary)); // Doesn't work
        };
        reader2.readAsBinaryString(blob);

        // console.log(URL.createObjectURL(atob(base64Image))); // Doesn't work

    };
    reader.readAsDataURL(file);
    console.log(URL.createObjectURL(file)); // Works
});

Thanks!

谢谢!

回答by sissonb

After some more research I found the answer from hereI basically needed to wrap the raw binary in an arraybuffer and convert the binary chars to Unicode.

经过更多研究,我从这里找到了答案, 我基本上需要将原始二进制文件包装在数组缓冲区中并将二进制字符转换为 Unicode。

This is the code that was missing,

这是缺少的代码,

    var binaryImg = atob(base64Image);
    var length = binaryImg.length;
    var ab = new ArrayBuffer(length);
    var ua = new Uint8Array(ab);
    for (var i = 0; i < length; i++) {
        ua[i] = binaryImg.charCodeAt(i);
    }

The full sample code is here

完整的示例代码在这里

回答by Bergi

URL.createObjectURLexpects a Blob(which can be a File) as its argument. Not a string. That's why URL.createObjectURL(file)works.

URL.createObjectURL期望 a Blob(可以是 a File)作为其参数。不是字符串。这就是为什么URL.createObjectURL(file)有效。

Instead, you are creating a FileReaderreaderthat reads fileas a data url, then you use that data url to create another Blob(with the same contents). And then you even create a reader2to get a binary stringfrom the just constructed blob. However, neither the base64Imageurl string part (even if btoa-decoded to a larger string) nor the decoded.binarystring are vaild arguments to URL.createObjectURL!

相反,您正在创建一个读取为数据 url数据 url,然后您使用该数据 url 创建另一个(具有相同内容)。然后,你甚至可以创建一个得到一个二进制字符串从刚刚构建的。但是,url 字符串部分(即使解码为更大的字符串)和字符串都不是!FileReaderreaderfileBlobreader2blobbase64Imagebtoadecoded.binaryURL.createObjectURL