Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >终端图像处理系列 - 图像混合模式的Shader实现

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

作者头像
天天P图攻城狮
发布于 2018-05-14 03:25:01
发布于 2018-05-14 03:25:01
4.5K10
举报
文章被收录于专栏:天天P图攻城狮天天P图攻城狮

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

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

除了普通混合模式外,还有多种图像混合模式,包括但不局限于:正片叠底(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工程师

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 天天P图攻城狮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
10 条评论
热度
最新
原来是这样做的
原来是这样做的
回复回复点赞举报
不会写啊
不会写啊
回复回复点赞举报
楼主方便教教详细的代码是怎么样的吗
楼主方便教教详细的代码是怎么样的吗
回复回复点赞举报
这是后端写好,推到前端吧,毕竟离线也能用
这是后端写好,推到前端吧,毕竟离线也能用
回复回复点赞举报
天天p图啥时候出个电脑版啊
天天p图啥时候出个电脑版啊
回复回复点赞举报
第二个人像,咋一看还以为是自己,撞脸了撞脸了
第二个人像,咋一看还以为是自己,撞脸了撞脸了
回复回复点赞举报
天天P图团队果然名不虚传,天天P图的使用体验非常棒
天天P图团队果然名不虚传,天天P图的使用体验非常棒
回复回复点赞举报
可以解释一下具体的公式含义吗,小白不是很懂
可以解释一下具体的公式含义吗,小白不是很懂
回复回复点赞举报
谢谢作者分享的算子。
谢谢作者分享的算子。
回复回复点赞举报
可不可以理解为为图片加滤镜?
可不可以理解为为图片加滤镜?
回复回复点赞举报
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档