终端图像处理系列 - 图像混合模式的Shader实现

在图像处理应用中,将两张或者多张图片混合显示是非常常见的一种操作,应用场景包括但不限于:加水印、标签,插入画中画,遮盖等等。

最常见的图像混合模式是普通混合模式,比如加水印。对于叠加在原图上的水印图片,其中根据透明度来选择原图和水印图片像素所占的权重,从而可以形成一个半透明的水印。

除了普通混合模式外,还有多种图像混合模式,包括但不局限于:正片叠底(multiply)、滤色模式(screen)、叠加模式(overlay)、柔光模式(softlight)、强光模式(hardlight)、增加模式(add)、减去模式(subtract)等等。每一种混合模式都对应了一种函数T=F(S,D),其中,T是混合后的像素颜色,S表示用于混合的像素颜色,D表示底图的像素颜色(S,D,T的取值范围都是0~1)。

下面是各种混合模式的计算公式,这里选择最常见的12种混合模式作为例子。其它的混合模式可以类似实现。

混合模式

公式

条件、备注

normal

T=S

multiply

T=S*D

screen

T=1-(1-S)*(1-D)

overlay

T=2*S*D

D<0.5

T=1-2*(1-S)*(1-D)

D>=0.5

hardlight

T= 2*S*D

S<0.5

T=1-2*(1-S)*(1-D)

S>=0.5

softlight

T=2*S*D+D*D*(1-2*S)

S<0.5

T=2*D*(1-S)+sqrt(D)*(2*S-1)

S>=0.5

divide

T=D/S

D/S取0~1之间

add

T=D+S

D+S取0~1之间

subtract

T=D-S

D-S取0~1之间

diff

T=|D-S|

darken

T=MIN(D,S)

lighten

T=MAX(D,S)

另外,当融合图片是半透明的时候(α值不是1),融合后的像素值T’=T*α+(1-α)*D。从中可以看出,当α为0时(全透明),T’=D,即融合图片不影响结果;当α为1时(不透明),T’=T。

具体的效果如下图所示:

底图:

融合图:

融合结果:

底图:

融合图:

融合结果:

看完了效果,那么,怎么在GPUImage里实现呢?这里就要实现自定义的FragmentShader了。

这里的返回值是T和S的α值,后续会有一个跟底图的α融合过程。该融合过程可以放在shader中实现,也可以让OpenGL自动实现。

  • 让OpenGL自动实现的方法如下:

1) 在render之前,设置:

这两句的含义是:让OpenGL根据α值自动融合结果;融合公式是:

T=S*α+(1-α)*D

2) glDrawArray

3) glDisable(GL_BLEND);

这样设置好之后,就可以实现原地多次增加贴图了(绘制在同一个frameBuffer上,不用两个frameBuffer来回倒腾),相当方便~

  • 在shader里面手动实现的方法如下:


更多关于移动开发,图像处理的相关技术,请持续关注我们的公众号!

作者简介:dreamqian(钱梦仁),外号"大魔王",天天P图iOS工程师

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
终端图像处理系列 - 图像混合模式的Shader实现
在图像处理应用中,将两张或者多张图片混合显示是非常常见的一种操作,应用场景包括但不限于:加水印、标签,插入画中画,遮盖等等...
<<上一篇
下一篇>>