一、Xfermode

Xfermode表明图层的混合形式,用于描绘两个图层之间进行融合时,像素点进行计算的规则。

在API16之前,Xfermode有3个子类:AvoidXfermode、PixelXorXfermode、PorterDuffXfermode。但在API16以后,前两个现已过期,乃至从源码里移除,所以咱们只需学习PorterDuffXfermode即可。

1.1、PorterDuffXfermode

PorterDuffXfermode最早是在1984年由Porter和Duff两人发表的论文《Compositing Digital Images》中出现,所以该混合形式也依据作者来命名。

PorterDuffXfermode结构函数需求指定一个PorterDuff.Mode,而PorterDuff.Mode在以下地方都会触及:

  • 1、ComposeShader
  • 2、Paint.setXfermode()
  • 3、PorterDuffColorFilter

它供给18种形式可选项:

PorterDuff.Mode 公式
PorterDuff.Mode.CLEAR alphaout=0alpha_{out} = 0
Cout=0C_{out} = 0
PorterDuff.Mode.SRC alphaout=alphasrcalpha_{out} = alpha_{src}
Cout=CsrcC_{out} = C_{src}
PorterDuff.Mode.DST alphaout=alphadstalpha_{out} = alpha_{dst}
Cout=CdstC_{out} = C_{dst}
PorterDuff.Mode.SRC_OVER alphaout=alphasrc+(1−alphasrc)∗alphadstalpha_{out} = alpha_{src} + (1 – alpha_{src}) * alpha_{dst}
Cout=Csrc+(1−alphasrc)∗CdstC_{out} = C_{src} + (1 – alpha_{src}) * C_{dst}
PorterDuff.Mode.DST_OVER alphaout=alphadst+(1−alphadst)∗alphasrcalpha_{out} = alpha_{dst} + (1 – alpha_{dst}) * alpha_{src}
Cout=Cdst+(1−alphadst)∗CsrcC_{out} = C_{dst} + (1 – alpha_{dst}) * C_{src}
PorterDuff.Mode.SRC_IN alphaout=alphasrc∗alphadstalpha_{out} = alpha_{src} * alpha_{dst}
Cout=Csrc∗alphadstC_{out} = C_{src} * alpha_{dst}
PorterDuff.Mode.DST_IN alphaout=alphasrc∗alphadstalpha_{out} = alpha_{src} * alpha_{dst}
Cout=Cdst∗alphasrcC_{out} = C_{dst} * alpha_{src}
PorterDuff.Mode.SRC_OUT alphaout=(1−alphadst)∗alphasrcalpha_{out} = (1 – alpha_{dst}) * alpha_{src}
Cout=(1−alphadst)∗CsrcC_{out} = (1 – alpha_{dst}) * C_{src}
PorterDuff.Mode.DST_OUT alphaout=(1−alphasrc)∗alphadstalpha_{out} = (1 – alpha_{src}) * alpha_{dst}
Cout=(1−alphasrc)∗CdstC_{out} = (1 – alpha_{src}) * C_{dst}
PorterDuff.Mode.SRC_ATOP alphaout=alphadstalpha_{out} = alpha_{dst}
Cout=alphadst∗Csrc+(1−alphasrc)∗CdstC_{out} = alpha_{dst} * C_{src} + (1 – alpha_{src}) * C_{dst}
PorterDuff.Mode.DST_ATOP alphaout=alphasrcalpha_{out} = alpha_{src}
Cout=alphasrc∗Cdst+(1−alphadst)∗CsrcC_{out} = alpha_{src} * C_{dst} + (1 – alpha_{dst}) * C_{src}
PorterDuff.Mode.XOR alphaout=(1−alphadst)∗alphasrc+(1−alphasrc)∗alphadstalpha_{out} = (1 – alpha_{dst}) * alpha_{src} + (1 – alpha_{src}) * alpha_{dst}
Cout=(1−alphadst)∗Csrc+(1−alphasrc)∗CdstC_{out} = (1 – alpha_{dst}) * C_{src} + (1 – alpha_{src}) * C_{dst}
PorterDuff.Mode.DARKEN alphaout=alphasrc+alphadst−alphasrc∗alphadstalpha_{out} = alpha_{src} + alpha_{dst} – alpha_{src} * alpha_{dst}
Cout=(1−alphadst)∗Csrc+(1−alphasrc)∗Cdst+min(Csrc,Cdst)C_{out} = (1 – alpha_{dst}) * C_{src} + (1 – alpha_{src}) * C_{dst} + min(C_{src}, C_{dst})
PorterDuff.Mode.LIGHTEN alphaout=alphasrc+alphadst−alphasrc∗alphadstalpha_{out} = alpha_{src} + alpha_{dst} – alpha_{src} * alpha_{dst}
Cout=(1−alphadst)∗Csrc+(1−alphasrc)∗Cdst+max(Csrc,Cdst)C_{out} = (1 – alpha_{dst}) * C_{src} + (1 – alpha_{src}) * C_{dst} + max(C_{src}, C_{dst})
PorterDuff.Mode.MULTIPLY alphaout=alphasrc∗alphadstalpha_{out} = alpha_{src} * alpha_{dst}
Cout=Csrc∗CdstC_{out} = C_{src} * C_{dst}
PorterDuff.Mode.SCREEN alphaout=alphasrc+alphadst−alphasrc∗alphadstalpha_{out} = alpha_{src} + alpha_{dst} – alpha_{src} * alpha_{dst}
Cout=Csrc+Cdst−Csrc∗CdstC_{out} = C_{src} + C_{dst} – C_{src} * C_{dst}
PorterDuff.Mode.ADD alphaout=max(0,min(alphasrc+alphadst,1))alpha_{out} = max(0, min(alpha_{src} + alpha_{dst}, 1))
Cout=max(0,min(Csrc+Cdst,1)C_{out} = max(0, min(C_{src} + C_{dst}, 1)
PorterDuff.Mode.OVERLAY alphaout=alphasrc+alphadst−alphasrc∗alphadstalpha_{out} = alpha_{src} + alpha_{dst} – alpha_{src} * alpha_{dst}
Cout={2∗Csrc∗Cdst2∗Cdst<dstalphasrc∗dst−2(dst−Csrc)(src−Cdst)otherwiseC_{out} = begin{cases} 2 * C_{src} * C_{dst} & 2 * C_{dst} lt alpha_{dst} \ alpha_{src} * alpha_{dst} – 2 (alpha_{dst} – C_{src}) (alpha_{src} – C_{dst}) & otherwise end{cases}

各种形式下的作用如下图所示:

  • 1、假如原图和方针图巨细共同(图中,两者巨细均占满整个小方格区域):

    五、Android制作常识总结(Xfermode和硬件加速)

  • 2、假如原图和方针图巨细不共同(图中,两者巨细为可见巨细):

    五、Android制作常识总结(Xfermode和硬件加速)

这里能够发现,两种作用是不一样的,谷歌官方给的是第一种,但是,通常情况应该是第二种,具体原因可参考该文章

比方咱们画一个矩形,应该按第二种作用来考虑,因为源图和方针图巨细不共同;假如画相同巨细的Bitmap,则按第一种做。

在实践应用中,咱们能够从以下三个方面来决议运用哪种形式:

1、方针图画和源图画混合,需不需求生成色彩的叠加特效。假如需求,则从色彩叠加相关形式中挑选,有Mode.ADD(饱和度相加)、Mode.DARKEN(变暗)、Mode.LIGHTEN(变亮)、Mode.MULTIPLY (正片叠底)、Mode.OVERLAY(叠加)、Mode.SCREEN(滤色)。
2、当不需求特效,而需求依据某张图片的通明像素来裁剪时,就需求运用SRC相关形式或DST相关形式了。而SRC相关形式与DST相关形式是相通的,唯一不同的是决议当前哪个图画是方针图画和源图画。
3、当需求清空图画时,运用Mode.CLEAR形式。

1.1、实例:

二、硬件加速

2.1、View的制作模型

1、没有硬件加速:

invalidate the view hierarchy ——> draw the view hierarchy

2、有硬件加速:

invalidate the view hierarchy ——> record and update the display list ——> draw the display list

2.2、敞开硬件加速后的反常

1、制作不正确:可能运用了不支撑硬件加速的操作, 需求封闭硬件加速或许绕过该操作

2、抛出反常:可能运用了不支撑硬件加速的操作, 需求封闭硬件加速或许绕过该操作

2.3、禁用GPU硬件加速

在Android系统中,有4个不同等级的翻开或许封闭硬件加速操作:

1、Application等级:

<application android:hardwareAccelerated="false">

默认为true,用于控制这个app是否敞开硬件加速。

2、Activity等级:

<activity android:hardwareAccelerated="false">

3、Window等级:(只支撑敞开操作)

getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

4、View等级:(只支撑封闭操作)

view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
LAYER_TYPE_HARDWARE,运用硬件加速(GPU)进行制作
LAYER_TYPE_SOFTWARE,运用CPU进行制作

或许布局文件中,指定以下属性:

android:layerType="software"

2.4、检测是否敞开硬件加速

1、view.isHardwareAccelerated()

假如回来true,表明view挂在一个敞开了硬件加速的Window之下,也就意味着,它在制作时,并不一定敞开了硬件加速。

2、canvas.isHardwareAccelerated()

假如回来true,因为着canvas在制作的时候启用了硬件加速,尽量选用此方法来判断是否敞开了硬件加速。