使用Base64对图像进行编码/解码会破坏图像。

8
我正在尝试对图像进行编码和解码。我正在使用FileReader的readAsDataURL方法将图像转换为base64。然后,我尝试使用readAsBinaryString()和atob()来将其转换回来,但没有成功。是否有其他方法可以持久化图像而无需对它们进行base64编码?
“readAsBinaryString()”开始读取指定Blob(可能是文件)的内容。当读取操作完成时,readyState将变为DONE,并且将调用onloadend回调函数(如果有)。此时,结果属性包含文件中的原始二进制数据。
这里我做错了什么?
示例代码 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
});

谢谢!


这个例子在哪个浏览器上可以运行?TypeError: encodedFile.srcElement is undefined。 - El Hocko
我正在使用Chrome进行测试,但我需要它能够在最新的Android和iOS浏览器中正常工作。 - sissonb
2个回答

14

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

这是缺失的代码:

    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);
    }

完整的样例代码在这里


1

URL.createObjectURL 需要一个 Blob(可以是一个 File)作为其参数,而不是字符串。这就是为什么 URL.createObjectURL(file) 起作用的原因。

相反,你正在创建一个 FileReader reader,它以数据URL的形式读取file,然后使用该数据URL创建另一个具有相同内容的Blob。然后,您甚至创建了一个reader2,从刚构建的blob中获取二进制字符串。但是,无论是base64Image URL字符串部分(即使btoa解码为较大的字符串),还是decoded.binary字符串都不是URL.createObjectURL的有效参数!


能否将 base64Image 转换回原始文件呢?我基本上是想用 readAsBinaryString()atob() 来撤销 reader.readAsDataURL(file); 的操作。 - sissonb
var blob = new Blob([base64Image],{type:"image/jpeg"}); 这样可以吗?试试 URL.createObjectURL(blob); - Bergi
它显示了一个URL.createObjectURL(blob);的损坏图像。我在这里更新了JSFiddle,http://jsfiddle.net/qL86Z/7/这是一个屏幕录制展示损坏的图片。 http://screencast.com/t/vVVGNTvo - sissonb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接