Android之玩转View(四):Paint之Xfermode的18种模式

Paint之Xfermode的18种模式

请尊重原创,转载请注明出处【tianyl】的博客

关于的Android之玩转View目录

前言

说到Xfermode,实现过圆形图像的同学一定不会陌生,虽说之前的Shader篇中介绍了一种用Shader实现圆形图像的方法,不过使用最广泛的,还是Xfermode

首先说明一下Xfermode是个什么东西,简单来讲,它就是将一张图片,根据另一张图片,来进行一些处理,来达到想要的显示效果,而它的处理方式,总共有18种,下面就来介绍一下这些处理方式

1 PorterDuff

PorterDuff.java是android.graphics包下的一个类,它有一个枚举的子类Mode,这个Mode类就定义了这18种处理方式

因为篇幅原因这里就不放代码了,直接贴图片


上图就是这18种处理模式,下图是它们的处理结果(还有两种新增的模式的图在后面)


下面来分别介绍它们的处理规则

1.1 颜色计算说明

首先说明,对于这18种模式,Android都是通过两张图片的颜色值进行特殊的计算,而得到一张新的图片进行实现的,用数组[x,y]表示(Sa表示原图的alpha值,Da表示目标图的alpha值,Sc表示原图的color值,Dc表示目标图的color值

其中x表示结果图片的alpha值,y表示结果图片的color值

1.2 PorterDuff.Mode.CLEAR

清除模式
Android源码中的颜色数组为[0,0]
很显然,这个模式下的图标就是什么都没有,如上图16种模式中的Clear

1.3 PorterDuff.Mode.SRC

原图模式
Android源码中的颜色数组为[Sa,Sc]
这个模式下的绘制出来的就是原图

1.4 PorterDuff.Mode.Dst

目标图模式
Android源码中的颜色数组为[Da, Dc]
这个模式下的绘制出来的就是目标图

1.5 PorterDuff.Mode.SRC_OVER

原图覆盖
Android源码中的颜色数组为[Sa + (1 - Sa)*Da, Sc + (1 - Sa)*Dc]
很显然,如果Sa透明度为1(即完全不透明,那么绘制的是原图,否则绘制的是目标图,如果是半透明那么两者都有)

显示出来的效果就是原图将目标图覆盖了

1.6 PorterDuff.Mode.DST_OVER

目标图覆盖
Android源码中的颜色数组为[Sa + (1 - Sa)*Da, Dc + (1 - Da)*Sc]
和SRC_OVER正好相反,就不解释了

显示出来的效果就是目标图将原图覆盖了

1.7 PorterDuff.Mode.SRC_IN

绘制原图,但是受目标图的alpha值影响
Android源码中的颜色数组为[Sa * Da, Sc * Da]
如果Da(目标图的alpha值)为0,那么数组的值就是[0,0],所以这个模式只会绘制两者相交的区域,并且相交区域受目标图的alpha值影响

1.8 PorterDuff.Mode.DST_IN

绘制目标图,受原图alpha值影响
Android源码中的颜色数组为[Sa * Da, Sa * Dc]
因为和SRC_IN相反,所以这里也不解释了

1.9 PorterDuff.Mode.SRC_OUT

绘制原图,去掉相交部分
Android源码中的颜色数组为[Sa * (1 - Da), Sc * (1 - Da)]
很显然,如果Da(目标图的alpha值)为1,那么数组值为[0,0],所以只会绘制目标图alpha值不为1的部分,并且最后颜色的也和目标图的alpha的值有关

1.10 PorterDuff.Mode.DST_OUT

绘制目标图,去掉相交部分
Android源码中的颜色数组为[Da * (1 - Sa), Dc * (1 - Sa)]
和SRC_OUT相反,解释略

1.11 PorterDuff.Mode.SRC_ATOP

主要绘制目标图,如果存在相交部分,则绘制原图
Android源码中的颜色数组为[Da, Sc * Da + (1 - Sa) * Dc]

显然,alpha的值为Da,所以只绘制目标图,而当Sa为1时(完全不透明)color值为Sc * Da,所以相交部分绘制原图,但是受Da值的影像

1.12 PorterDuff.Mode.DST_ATOP

主要绘制原图,如果存在相交部分,则绘制目标图
Android源码中的颜色数组为[Sa, Sa * Dc + Sc * (1 - Da)]

和SRC_ATOP相反,解释略

1.13 PorterDuff.Mode.XOR

异或模式,相交部分不绘制,绘制不相交部分
Android源码中的颜色数组为[Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]

显然,alpha的值为Sa + Da - 2 * Sa * Da,只有Sa=Da=1的时候,这个值为0,也就是两者完全不透明并且相交的时候不绘制,除此之外都会绘制
color值受两者的color值影响,计算公式是:Sc * (1 - Da) + (1 - Sa) * Dc

1.14 PorterDuff.Mode.DARKEN

字面翻译就是变暗模式,两者都绘制,并且在两者相交的位置对颜色进行处理(也就是所谓的变暗)
Android源码中的颜色数组为[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]

alpha值为Sa + Da - Sa*Da,因为alpha的值在0到1之间,所以alpha值是增大的,所以更加不透明了
color值为Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)

1.15 PorterDuff.Mode.LIGHTEN

和DARKEN相反,字面意思就是变亮
Android源码中的颜色数组为[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
alpha计算和DARKEN一样,更加不透明,颜色计算这里取的是max(Sc, Dc),而DARKEN里取的是min(Sc, Dc),我们知道颜色越小就越暗(黑色是000000,白色是ffffff)

1.16 PorterDuff.Mode.MULTIPLY

字面翻译就是正片叠底,只绘制相交区域,并处理
Android源码中的颜色数组为[Sa * Da, Sc * Dc]

显然,当Sa为0或者Da为0的时候,全透明,只有当两者都不透明时,绘制图像,color值为Sc * Dc

1.17 PorterDuff.Mode.SCREEN

字面翻译就是屏幕(说好听一点叫滤色),绘制所有区域,并处理
Android源码中的颜色数组为[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]

1.18 PorterDuff.Mode.ADD

叠加饱和度,这个算是后面加的一种模式
官方文档上的alpha值和color值计算规则


效果图如下


1.19 PorterDuff.OVERLAY

叠加模式
官方文档上的alpha值和color值计算规则


效果图如下


由于后两者ADD模式和OVERLAY是后面加的,所有这里就直接使用Google官方的效果图展示了

1.20 总结

到此,关于Xfermode的18种模式就介绍完了,当然,关于这些模式中的颜色计算和图片计算,本文都只是说明了一个大概,具体的含义并没有深究(毕竟我只是一个程序员,不懂美术啊),如果有同学对这方面有兴趣,可以看一下这篇科普,关于部分颜色处理公式的物理含义都有解释

最后,由于这部分内容是科普向的内容,就不放demo展示了,后续做一些特效实现吧(ˇˍˇ)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352