【问题标题】:Why image data encoded into base64 decodes back with wrong values? [duplicate]为什么编码为 base64 的图像数据会以错误的值解码? [复制]
【发布时间】:2022-02-23 11:41:24
【问题描述】:

我正在尝试将数组转换为 base64 字符串。然后又回来了。我做了一个简单的示例,示例数组如下所示:[0, 1, 2, 3, 0, 1, 2, 3] 并在画布中使用.toDataURL() 进行转换。但由于某种原因,当我读回 base64 字符串并将其应用到画布时,它返回不同的图像数据[0, 0, 0, 3, 0, 0, 0, 3]

为什么会这样?

例子:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

const array = new Uint8ClampedArray([0, 1, 2, 3, 0, 1, 2, 3]);
const initialImageData = new ImageData(array, 2, 1);

ctx.putImageData(initialImageData, 0, 0);
const dataURL = canvas.toDataURL();

console.log(dataURL); // data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAAAAXNSR0IArs4c6QAAAA9JREFUGFdjZGBgYGYAAgAAIQAFoFclWQAAAABJRU5ErkJggg==

const img = new Image();
img.onload = () => {
    canvas.width = 2;
    canvas.height = 1;
    ctx.drawImage(img, 0, 0);
    const imageData = ctx.getImageData(0, 0, 2, 1);
    console.log(imageData.data); // [0, 0, 0, 3, 0, 0, 0, 3]
}
img.src = dataURL;

【问题讨论】:

    标签: javascript image canvas base64


    【解决方案1】:

    你好像被this gotcha in the Canvas implementation抓到了:

    警告:由于与预乘 Alpha 颜色值相互转换的有损特性,刚刚使用 putImageData() 设置的像素可能会作为不同的值返回到等效的 getImageData()。

    (强调我的)

    您传入的Uint8ClampedArray 格式为[r, g, b, a],而Alpha (a) 组件非常重要。在您的测试中,您提供了 3 的 Alpha 值,并且浏览器似乎选择将其他像素“优化”为 0

    尝试a 的完全不透明度值,一切正常:

    const array = new Uint8ClampedArray([0, 1, 2, 255, 0, 1, 2, 255]);
    
    ...
    
    console.log(imageData.data); // [0, 1, 2, 255, 0, 1, 2, 255]
    

    【讨论】:

    • 哦,不...谢谢您提供的信息。但是改变不透明度值对我来说不是这样。因为我在这里所做的是试图将大量数字(超过 200 万)转换为“压缩的”base64 字符串。打算以后再读。因此,在我的情况下,数据丢失或更改是不可接受的。附言对我来说,这与视觉图像无关,而是一种压缩大量数据的替代方法。
    • 啊,我看到了@AlekseiS。 - 鉴于Canvas 实现的上述潜在损失,它可能不是压缩数据数组的可行方法(虽然很聪明!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多