在 p5.js 中绘制半透明时转换颜色



在 p5 中绘制颜色时似乎应用了转换.js alpha 值低于 255:

for (const color of [[1,2,3,255],[1,2,3,4],[10,11,12,13],[10,20,30,40],[50,100,200,40],[50,100,200,0],[50,100,200,1]]) {
clear();
background(color);
loadPixels();
print(pixels.slice(0, 4).join(','));
}
Input/Expected Output   Actual Output (Firefox)
1,2,3,255               1,2,3,255 ✅
1,2,3,4                 0,0,0,4
10,11,12,13             0,0,0,13
10,20,30,40             6,19,25,40
50,100,200,40           51,102,204,40
50,100,200,0            0,0,0,0
50,100,200,1            0,0,255,1

保留 alpha 值,但 RGB 信息会丢失,尤其是在低 alpha 值时。

这使得可视化变得不可能,例如,首先绘制 2D 形状,然后通过更改 alpha 值对某些区域的可见性进行动画处理。

是否可以关闭这些转换,或者是否可以以任何方式预测这些转换?

更新:该行为并非特定于 p5.js:

const ctx = new OffscreenCanvas(1, 1).getContext('2d');
for (const [r,g,b,a] of [[1,2,3,255],[1,2,3,4],[10,11,12,13],[10,20,30,40],[50,100,200,40],[50,100,200,0],[50,100,200,1]]) {
ctx.clearRect(0, 0, 1, 1);
ctx.fillStyle = `rgba(${r},${g},${b},${a/255})`;
ctx.fillRect(0, 0, 1, 1);
console.log(ctx.getImageData(0, 0, 1, 1).data.join(','));
}

我可能离这里很远...但在内部看起来,在background方法中,如果_isErasing为 true,则调用blendMode。默认情况下,这将应用颜色的线性插值。

见 https://github.com/processing/p5.js/blob/9cd186349cdb55c5faf28befff9c0d4a390e02ed/src/core/p5.Renderer2D.js#L45

请参阅 https://p5js.org/reference/#/p5/blendMode

混合 - 颜色的线性插值:C = A*因子 + B。这是 默认混合模式。

因此,如果您将混合模式设置为REPLACE我认为它应该可以工作。

替换 - 像素完全替换其他像素,不使用 阿尔法(透明度)值。

blendMode(REPLACE);
for (const color of [[1,2,3,255],[1,2,3,4],[10,11,12,13],[10,20,30,40],[50,100,200,40],[50,100,200,0],[50,100,200,1]]) {
clear();
background(color);
loadPixels();
print(pixels.slice(0, 4).join(','));
}

在内部,HTML 画布以不同的方式存储颜色,在完全透明时无法保留 RGB 值。写入和读取像素数据时,由于用 8 位数字表示,会发生有损的转换。

以上面测试中的这一行为例:

Input/Expected Output   Actual Output
10,20,30,40             6,19,25,40
IN (conventional alpha)RGB A
10203040 (= 15.6%)

相关内容

  • 没有找到相关文章

最新更新