用html5画布混合两个图像

时间:2014-10-05 08:07:02

标签: javascript html5 canvas html5-canvas alphablending

我需要在相同的图像上绘制2个相同图像的变体,其alpha值加起来为1.

例如:
- imageA的字母为0.4,而imageB的字母为0.6
- 所需的结果是完全不透明的图像(每个像素的1.0的alpha),显示为imageB的60%混合,以及imageA的40%混合。

但是,我认为默认情况下html5画布使用的是混合模式,而不是添加alpha混合图像,因此使用低于1的alpha绘制的两个内容不会加起来为1。  我尝试了所有不同的合成模式,以及Adobe混合模式,但没有一个具有所需的结果 一个简单的测试用例是绘制一个洋红色矩形两次,两者都是0.5的alpha。我希望得到的像素为rgb(255, 0, 255)。但是,结果略显透明。

有谁知道实现这一结果的某种方式?

1 个答案:

答案 0 :(得分:3)

•如果你看一下关于默认混合模式的canvas'context2D规范('source-over'):

http://dev.w3.org/fxtf/compositing-1/#simplealphacompositing

您将看到使用的公式是(为了清楚起见,我重命名了变量):

colorOut = prevColor x prevAlpha + newColor x newAlpha x (1 - prevAlpha)

结果是alpha:

αlphaOut = prevAlpha + newAlpha x (1 - prevAlpha)

请注意,
   a)出乎意料的是,公式不是线性的(由于:newAlpha x(1 - prevAlpha)因子)    b)一个点两个较小的r,g,b值减少了alpha。所以当重新使用它时,它 将为最终图像贡献square(0.6)== 0.36。 (......完全反直觉......)

•那么你的60%/ 40%抽奖会发生什么?

1)图像A绘制为alpha = 60%。 上面的公式给出了:

 colorOut = color_A * 0.6 ;
 alphaOut = 0.6 ;

2)用α= 40%

绘制图像B.
 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手动完成。请注意Cross-Origin问题:如果您的图片不是来自您的域,则他们的imageData将为空。对于表演,与执行作业的画布(= GPU)相比,下注50+减速因子。 “实时”(= 60fps)可能无法实现,具体取决于图像大小/计算能力/浏览器。但你有完全的控制权。

2)但是如果你现在看看'ligther'复合模式,我们似乎有了这个人:

http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators_plus

公式现在是:

colorOut = prevColor x prevAlpha + newColor x newAlpha 

结果是alpha:

 αlphaOut = prevAlpha + newAlpha 

您会发现这是一个简单的“加号”运算符,非常适合您的要求 所以解决方案是:
   - 保存ctx。
   - 设置较轻的复合模式    - 以60%的阿尔法绘制第一张图像    - 以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] ) ;
 }
相关问题