Android笔记之Xfermode

Xfermode是Android中用来指示Paint绘制的内容与View中已有内容的混合计算方式,也就是用来确定图形绘制到目标图形的时候,如何处理两个图形重合部分的颜色变化。共18个,分为Alpha合成和混合两种。

设要绘制的图形为src,已经绘制好的图形为dst

需要注意的是,这些图片除了要绘制的图形有着色之外,其他部分要为透明,并且包括透明区域在内的图片大小(宽高)要能完全覆盖另外一张图片的图形区域,否则绘制出的图形可能与预设的效果不一致

按照官方的定义,不同Xfermode绘制结果如下:

注意事项

要实现如上效果,需要注意:

  • srcdst符合要求(要有合适的透明区域)

    这是因为xfermode的效果,使用透明部分的像素与已有图形对应位置交叉作用,得出所需要的效果,如果透明区域过小,则无法作用到对应的图形。下面这个来自Hencoder.com的图可以很形象的解释:

  • 在新的图层绘制(在新的图层按照xfermode规则绘制,然后再将其绘制到原有图层):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //新建图层   
    val saveCount = canvas.saveLayer(0F,0F,width.toFloat(),height.toFloat(),null,Canvas.ALL_SAVE_FLAG)

    //dst 已经绘制的图形 ; src 我们要绘制的图形
    canvas.drawBitmap(dst,0F, 0F, dstPaint)

    srcPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)
    canvas.drawBitmap(src,0F, 0F, srcPaint)
    srcPaint.xfermode = null

    //将新图层绘制到原有图层上
    canvas.restoreToCount(saveCount)
  • 关闭硬件加速(可选)

    硬件加速的本质是把一部分CPU计算的工作量交给GPU完成,可以加速绘制速度。

    但是由于硬件加速不支持canvas.drawXXX()的部分方法,为了避免在某些机型上面无法使用这些方法,可以关闭硬件加速:

    1
    view.setLayerType(LAYER_TYPE_SOFTWARE, null);

    关于硬件加速更详细的说明可以参考这里:HenCoder Android 自定义 View 1-8 硬件加速

Xfermode分类

HenCoder.com关于PorterDuff.Mode.DST_IN的动画解释:

可以看出,Xfermode的本质是处理dstsrc重合与未重合部分的展示与否,以及颜色变化。

这里的“重合部分”与“未重合部分”,其实也包括了各个图形的透明部分,将dstsrc的透明与不透明颜色相互作用,才会出现下述效果。

名称 含义
CLEAR 清除所有内容
DST 只绘制DST
DST_ATOP 先绘制SRC,再在顶部绘制DSTSRC重合的部分
DST_IN 只绘制DSTSRC重合部分
DST_OUT 只绘制DSTSRC未重合部分
DST_OVER DST绘制在SRC上面
SRC 只绘制SRC
SRC_ATOP 先绘制DST,再在顶部绘制SRCDST重合的部分
SRC_IN 只绘制SRCDST重合部分
SRC_OUT 只绘制SRCDST未重合部分
SRC_OVER SRC绘制在DST上面
XOR
ADD
DARKEN
LIGHTEN
MULTIPLY
OVERLAY
SCREEN

各个效果如下(源码及使用见github):

参考文献

HenCoder Android 开发进阶: 自定义 View 1-2 Paint 详解

HenCoder Android 自定义 View 1-8 硬件加速

PorterDuff.Mode