Paint之Xfermode

937 阅读3分钟

Xfermode简介

通过使用Xfermode将绘制的图形的像素和Canvas上对应位置的像素按照一定的规则进行混合,形成新的像素,再更新到Canvas中形成最终的图形

使用的时候都是通过Paint.setXfermode,并且需要开启软件加速View.setLayerType(LAYER_TYPE_SOFTWARE, null);

我们一个像素的颜色都是由四个分量组成,即ARGB,A表示的是我们Alpha值,RGB表示的是颜色

S表示的是原像素,原像素的值表示[Sa,Sc] Sa表示的就是源像素的Alpha值,Sc表示源像素的颜色值

D表示的是目标像素,目标像素的值表示[Da,Dc] Da表示的就是目标像素的Alpha值

蓝色矩形表示的是源图片,黄色圆表示的是目标图片

//先绘制目标图片
mPaint.setColor(mYellowColor);
canvas.drawCircle(centerX, centerY, radius, mPaint);
//设置Xfermode
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//再绘制源图片
mPaint.setColor(mBlueColor);
canvas.drawRect(mRect, mPaint);
//最后重置Xfermode
mPaint.setXfermode(null);

image.png

Xfermode分类

1、SRC类----优先显示的是源图片

  • SRC [Sa, Sc] ---- 处理图片相交区域时,总是显示的是原图片

  • SRC_IN [Sa * Da, Sc * Da] ---- 处理图片相交区域时,受到目标图片的Alpha值影响 当我们的目标图片为空白像素的时候,目标图片也会变成空白 简单的来说就是用目标图片的透明度来改变源图片的透明度和饱和度,当目标图片的透明度为0时,源图片就不会显示

    应用:圆角头像 、倒影图片

    //dst
    canvas.drawCircle(100, 100, 100, mPaint);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    //src
    canvas.drawBitmap(newBitmap, 0, 0, mPaint);
    
  • SRC_OUT [Sa * (1 - Da), Sc * (1 - Da)] --- 同SRC_IN类似 (1 - Da) 用我们目标图片的透明度的补值来改变源图片的透明度和饱和度,当目标图片的透明度为不透明时,源图片就不会显示

    应用:橡皮擦效果、刮刮卡
    目标图片 --- 手势的轨迹 源图片 --- 擦除的图片

  • SRC_ATOP [Da, Sc * Da + (1 - Sa) * Dc] ---- 当透明度为100%和0%时,SRC_IN 和 SRC_ATOP是通用的 当透明度不为上述的两个值时,SRC_ATOP 比 SRC_IN 源图像的饱和度会增加,变得更亮一些

    应用:圆角头像 、倒影图片 对比一下SRC_IN

2、DST类----优先显示的是目标图片

  • DST_IN [Sa * Da, Sa * Dc] ----- 对比一下SRC_IN,正好和我们SRC_IN想法,在相交的时候以源图片的透明度来改变目标图片的透明度和饱和度。当源图片的透明度为0的时候,目标图片完全不显示。

    应用:心电图效果,不规则水波纹效果,当然也可以做SRC_IN 的效果(注意选择谁为源图片,谁为目标图片)
    心电图效果-目标图片 ---心电图
    源图片 ---- 不透明的图 就是通过改变透明图片的不透明区域的宽度,来实现心电图的动画效果

3、其他的叠加效果

  • MULTIPLY[Sa * Da, Sc * Dc]

    应用:可以把图片的轮廓取出来

  • LIGHTEN -- 变亮

    应用:书架 头顶灯光变亮效果