具有透明度的HTML Canvas putImageData会导致保存不正确的RGB

HTML Canvas putImageData with transparency causes incorrect RGB to be saved

本文关键字:保存 不正确 RGB putImageData 透明度 HTML Canvas      更新时间:2024-05-20

我正在尝试使用putImageData()设置HTML画布中的各个像素。当我这样做,然后立即使用getImageData()读取这些像素时,我刚刚设置的RBG值已经更改!参见示例:

var ct = canvas.getContext('2d');
var image = ct.getImageData(0,0,1,1);
var data = image.data;
data[0] = 200; //r
data[1] = 100; //g
data[2] = 50; //b
data[3] = 25; //a
console.log(data); //[200, 100, 50, 25]  Yeah :)
ct.putImageData(image,0,0);
var debug = ct.getImageData(0,0,1,1);
console.log(debug.data); //[204, 102, 51, 25] Boo :(

如果我将alpha通道设置为255(无透明度),则RGB值不会更改。如果我将alpha通道设置为0(透明),则RGB将返回为0,0,0。显然,这与透明度有关。这可能与RGB颜色空间和数学有关。

我正试图弄清楚为什么会发生这种情况,或者至少能够以某种方式预测结果。有人能告诉我这里发生了什么吗?

这是由于合成过程,尤其是alpha通道的预乘。标准规定:

由于转换为预乘阿尔法和从预乘阿尔法转换的损耗性质颜色值,刚刚使用putImageData()设置的像素可能会作为不同的值返回到等效的getImageData()。

这是一个相对深入和广泛的话题,但如果你想深入了解它背后的数学细节,我建议你看看这个链接上的Porter-Duff算法。请特别参见混合和alpha合成。还考虑到浏览器在这些公式中使用8位整数值。