在 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) | R | G | B A | |
---|---|---|---|---|
值 | 10 | 20 | 30 | 40 (= 15.6%) |