Android自定义View-混合模式

352 阅读3分钟

在Paint中通过设置Xfermode来实现混合模式。

Xfermode是空实现,主要是用他的子类来实现不同的效果。

Xfermode的子类经常使用的有PorterDuffXfermode。

PorterDuffXfermode部分支持硬件加速。所以我们在使用Xfermode的时候应该关闭硬件加速。

我们还需要注意的是我们应该用离屏绘制,就是将代码写在canvas.saveLayer(),canvas.restoreToCount()之间。

PorterDuffXfermode

public PorterDuffXfermode(PorterDuff.Mode mode)

他只有一个构造函数,传入一个PorterDuff.Mode,表示混合的模式,枚举值有18个。 1652829696369.jpg 混合模式是计算DST(目标图像)和SRC(源图像)的alpha和color来设置的。

在设置Xformade之前画的图像叫目标图像,设置Xfermode之后的图像叫源图像。

在公式中Sa是源图像的alpha通道,Sc是源图像的color,Da表示目标图片的alpha通道,Dc表示标目图片的color。公式一般分为两部分,就拿DST_IN来说,[SaDa,SaDc]用逗号隔开,前面是计算alpha,后面是计算color。

[SaDa,SaDc]这个公式我们可以看出,重合的地方alpha因为都是1,所以得出的alpha是1。Sa是源图像alpha,Dc是目标图片的color,所以他们重合的地方就是目标颜色,没有重合的地方因为Da为0,所以不显示。

颜色叠加相关模式

Mode.ADD(饱和度相加)

将SRC和DST两个图片相交区域饱和度进行相加

Saturate(S + D)

Mode.LIGHTEN(变亮)

两个图片重合的地方,颜色值有变化

Mode.DARKEN(变暗)

对应photoshop变暗模式

Mode.MULTIPLY(正片叠底)

Sa * Da, Sc * Dc

根据公司可以看出alpha值是Sa*Da,目标图片和源图片没有相交的地方,目标图片alpha是0,所以得出来alpha也是0,所以源图片该区域不会展示。

Mode.OVERLAY(叠加)

Mode.SCREEN(滤色)

图像模式

以源图像显示为主的模式

Mode.SRC

Sa,Sc

从公式看出,相交区域以源图像显示

Mode.SRC_IN

Sa * Da, Sc * Da

可以看出alpha和color都依赖目标图片的alpha值,所以在没有和目标图片重合的地方就是透明的。重合的地方显示的是源图像

Mode.SRC_OUT

Sa * (1-Da), Sc * (1-Da)

当目标图片完全不透明的时候,源图像和目标图像重合的时候就是完全透明的。

Mode.SRC_OVER

Sa + (1 - Sa)*Da,Sc + (1 - Sc)*Dc

当源图像alpha为1的时候,不会有任何变化,当源图像alpha不为1的时候,相交的部分alpha和color都为1,不想交的部分就是正常的透明度

Mode.SRC_ATOP

Da, Sc * Da + (1 - Sa) * Dc

目标图像模式和其他模式

目标图像模式都是DST_xxx,该模式是以相交部分的目标图像显示为主。上面的都是SRC_xxx,这都是以相交的源图像显示为主。

Mode.DST

Da, Dc

Mode.DST_IN

Sa * Da, Sa * Dc

Mode.DST_OUT

Da * (1 - Sa), Dc * (1 - Sa)

相交区域的透明度和饱和度都是以目标图像稳准,但是是否展示要看源图像,假如源图像alpha为1,那么就不会展示,假如为0,就会完全展示。

Mode.DST_OVER

Sa + (1 - Sa) * Da, Rc = Dc + (1 - Da) * Sc

Mode.DST_ATOP

Sa , Sa * Dc + Sc * (1 - Da)

其他模式

Mode.CLEAR

0 , 0

相交区域都是空白的,都不展示