跳至主要內容

Android 笔记之 Xfermode

JI,XIAOYONG...大约 3 分钟android

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

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

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

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

注意事项

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

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

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

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

    //新建图层
    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()的部分方法,为了避免在某些机型上面无法使用这些方法,可以关闭硬件加速:

    view.setLayerType(LAYER_TYPE_SOFTWARE, null);
    

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

Xfermode 分类

HenCoder.comopen in new window关于PorterDuff.Mode.DST_IN的动画解释:

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

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

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

各个效果如下 (源码及使用见githubopen in new window):

参考文献

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

HenCoder Android 自定义 View 1-8 硬件加速open in new window

PorterDuff.Modeopen in new window

文章标题:《Android 笔记之 Xfermode》
本文作者: JI,XIAOYONG
发布时间: 2020/04/15 14:05:03 UTC+8
更新时间: 2023/12/30 16:17:02 UTC+8
written by human, not by AI
本文地址: https://jixiaoyong.github.io/blog/posts/104c9058.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 许可协议。转载请注明出处!
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8