Javascript 用html5画布混合两幅图像
我需要画两个相同图像的变体,它们的alpha值加起来等于1 例如: -imageA的alpha为0.4,而imageB的alpha为0.6。 -理想的结果是每个像素的完全不透明图像alpha为1.0,显示为imageB的60%混合,imageA的40%混合 然而,我相信html5画布在默认情况下使用的是混合模式,而不是添加alpha混合图像,因此,使用低于1的alpha绘制的两个东西加起来不会达到1。 我尝试了所有不同的合成模式,以及Adobe混合模式,但没有一个达到预期的效果。 一个简单的测试用例是绘制两次洋红色矩形,两者的alpha值均为0.5。我希望得到的像素是rgb255、0、255。然而,结果是略微透明的Javascript 用html5画布混合两幅图像,javascript,html,canvas,html5-canvas,alphablending,Javascript,Html,Canvas,Html5 Canvas,Alphablending,我需要画两个相同图像的变体,它们的alpha值加起来等于1 例如: -imageA的alpha为0.4,而imageB的alpha为0.6。 -理想的结果是每个像素的完全不透明图像alpha为1.0,显示为imageB的60%混合,imageA的40%混合 然而,我相信html5画布在默认情况下使用的是混合模式,而不是添加alpha混合图像,因此,使用低于1的alpha绘制的两个东西加起来不会达到1。 我尝试了所有不同的合成模式,以及Adobe混合模式,但没有一个达到预期的效果。 一个简单的测试
有人知道实现这一结果的方法吗?•如果您查看canvas关于默认混合模式“源代码结束”的context2D规范: 您将看到使用的公式是:为了清晰起见,我重命名了变量:
colorOut = prevColor x prevAlpha + newColor x newAlpha x (1 - prevAlpha)
对于生成的alpha:
αlphaOut = prevAlpha + newAlpha x (1 - prevAlpha)
αlphaOut = prevAlpha + newAlpha
注意,,
a出乎意料的是,由于:newAlpha x 1-prevAlpha因子,公式不是线性的。
b a点既有较小的r、g、b值,又有较小的α值。因此,当重新使用它时,它
将为最终图像贡献平方0.6==0.36。。。完全违反直觉
•那么,您的60%/40%提款会发生什么情况
1图像A以α=60%绘制。
上述公式给出:
colorOut = color_A * 0.6 ;
alphaOut = 0.6 ;
2图像B以alpha=40%绘制
colorOut = color_A * 0.6 * 0.6 + color_B x 0.4 x (0.4);
alphaOut = 0.6 + 0.4 * 0.4;
所以最后的公式是==>
colorOut = 0.36 * color_A + 0.16 * color_B ;
alphaOut = 0.76 ;
你看,这根本不是你所期望的60/40组合
•如何修复
1您可以使用getImageData/putImageData手动完成。请注意跨源问题:如果您的图像不是来自您的域,则其图像数据将为空。对于性能,与canvas=执行任务的GPU相比,赌50+的减速系数根据图像大小/计算能力/浏览器,实时'=60fps可能不可能。但你有完全的控制权
2但如果你现在看看“利瑟”复合模式,我们似乎有了我们的人:
现在的公式是:
colorOut = prevColor x prevAlpha + newColor x newAlpha
对于生成的alpha:
αlphaOut = prevAlpha + newAlpha x (1 - prevAlpha)
αlphaOut = prevAlpha + newAlpha
您可以看到,这是一个简单的“加号”运算符,非常适合您的要求。
因此,解决方案是:
-保存ctx。
-设置较轻的复合模式。
-以60%的alpha绘制第一幅图像。
-以40%的alpha绘制第二个图像。
-恢复ctx
最后一句话:如果要检查最终alpha是否正确==255,请使用此类函数:
function logAlpha(ctx,x,y) {
var imDt = ctx.getImageData(x,y,1,1).data;
if (!(imDt[0] || imDt[1] || imDt[2])) console.log('null point. CORS issue ?');
console.log(' point at (' +x+ ',' +y+ ') has an alpha of ' + imDt[3] ) ;
}
“打火机”对我有用。非常感谢!非常翔实的回答。