Android PorterDuff.Mode 的介绍

转载于

http://hencoder.com/ui-1-2/

官方文档

https://developer.android.com/reference/android/graphics/PorterDuff.Mode.html

各模式介绍

具体来说, PorterDuff.Mode 一共有 17 个,可以分为两类:

Alpha 合成 (Alpha Compositing)
混合 (Blending)
第一类,Alpha 合成,其实就是 「PorterDuff」 这个词所指代的算法。 「PorterDuff」 并不是一个具有实际意义的词组,而是两个人的名字(准确讲是姓)。这两个人当年共同发表了一篇论文,描述了 12 种将两个图像共同绘制的操作(即算法)。而这篇论文所论述的操作,都是关于 Alpha 通道(也就是我们通俗理解的「透明度」)的计算的,后来人们就把这类计算称为Alpha 合成 ( Alpha Compositing ) 。

日常使用过程中

Android PorterDuff.Mode 的介绍

源图像和目标图像

Android PorterDuff.Mode 的介绍

Alpha 合成

Android PorterDuff.Mode 的介绍

混合

Android PorterDuff.Mode 的介绍

实际应用

Android PorterDuff.Mode 的介绍

Xfermode 注意事项

Xfermode 使用很简单,不过有两点需要注意:

1. 使用离屏缓冲(Off-screen Buffer)

实质上,上面这段例子代码,如果直接执行的话是不会绘制出图中效果的,程序的绘制也不会像上面的动画那样执行,而是会像这样:

Android PorterDuff.Mode 的介绍

为什么会这样?
按照逻辑我们会认为,在第二步画圆的时候,跟它共同计算的是第一步绘制的方形。但实际上,却是整个 View 的显示区域都在画圆的时候参与计算,并且 View 自身的底色并不是默认的透明色,而且是遵循一种迷之逻辑,导致不仅绘制的是整个圆的范围,而且在范围之外都变成了黑色。就像这样:

Android PorterDuff.Mode 的介绍

这……那可如何是好?
要想使用 setXfermode() 正常绘制,必须使用离屏缓存 (Off-screen Buffer) 把内容绘制在额外的层上,再把绘制好的内容贴回 View 中。也就是这样:

Android PorterDuff.Mode 的介绍

通过使用离屏缓冲,把要绘制的内容单独绘制在缓冲层, Xfermode 的使用就不会出现奇怪的结果了。使用离屏缓冲有两种方式:

如果没有特殊需求,可以选用第一种方法 Canvas.saveLayer() 来设置离屏缓冲,以此来获得更高的性能。更多关于离屏缓冲的信息,可以看官方文档中对于硬件加速的介绍。

2. 控制好透明区域

使用 Xfermode 来绘制的内容,除了注意使用离屏缓冲,还应该注意控制它的透明区域不要太小,要让它足够覆盖到要和它结合绘制的内容,否则得到的结果很可能不是你想要的。我用图片来具体说明一下:
Android PorterDuff.Mode 的介绍

如图所示,由于透明区域过小而覆盖不到的地方,将不会受到 Xfermode 的影响。