Paint之Xfermode实战

Paint之Xfermode实战

Xfermode定义

Xfermode在文档中的定义为:用于在绘图管道中实现自定义“传输模式”的对象的基类。PorterDuff.Mode类定义了所有可用的模式,当通过setXfermode(Xfermode xfermode)方法将Xfermode设置给Paint时,该画笔就应用了Xfermode,当设置为null时,则是取消设置。

三个子类

Xfermode有三个子类实现,包括AvoidXfermode、PixelXorXfermode、PorterDuffXfermode。其中AvoidXfermode、PixelXorXfermode已经弃用。

AvoidXfermode

AvoidXfermode用于颜色去除,从命名上看Avoid即避免显示某种颜色的意思。

AvoidXfermode(int opColor, int tolerance, Mode mode)

AvoidXfermode构造函数有三个参数:opColor为基准色,tolerance为差值(0-255),mode为模式,有AVOID、TARGET两种模式。

在TARGET模式下,会将原图像中颜色为opColor,或与opColor的差值不超过tolerance的像素点,覆盖为画笔的颜色,当然要提前为画笔Paint设置好颜色。
在AVOID模式下,则相反,与opColor差不多的像素点保持不变,而剩下颜色的像素点会覆盖为画笔颜色。
下面是利用一张图片做的实例:

由图可见,在Avoid模式下,除去 黑色以及和黑色差值不超过100的像素点 会被渲染成蓝色。在Target模式下,黑色以及与黑色差值不超过150的像素点 会被渲染成蓝色。

注:由于此类实现在硬件加速条件下无效,所以需关闭Application或Activity的硬件加速属性。

PixelXorXfermode

PixelXorXfermode实现了简单的像素按位异或运算,计算公式为op ^ src ^ dst,op为基准色,src为原色,dst为画笔颜色。此转换不遵循预先约定,因此此模式始终返回不透明颜色(alpha == 255)。 因此,对混合颜色进行操作并不真正有用。

public PixelXorXfermode(int opColor)
构造函数只包含一个基准色。

下面的示例可以展示出此模式的作用。

PorterDuffXfermode

PorterDuffXfermode是画笔转换模式的专业实现,PorterDuff.Mode枚举类中定义了16种可用的Alpha合成和5种颜色混合模式。如下图所示:

实例关键代码:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //画布默认背景色是黑色,所以需要加一个透明背景
    canvas.drawColor(0x00000000);
    //先保存当前图层
    int sc = canvas.saveLayer(0, 0, W, H, null, Canvas.ALL_SAVE_FLAG);

    //声明一个新图层,画一个圆,作为目的图层
    Canvas canvasDst = new Canvas(mDstB);
    Paint paintDst = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintDst.setColor(0xFFFFCC44);
    canvasDst.drawCircle(500, 500, 200, paintDst);

    //声明一个新图层,画一个黑色半透明背景,作为原元图层
    Canvas canvasSrc = new Canvas(mSrcB);
    Paint paintSrc = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintSrc.setColor(0xd9000000);
    canvasSrc.drawRect(0, 0, W, H, paintSrc);

    //将原图层画到主图层上
    canvas.drawBitmap(mSrcB, 0, 0, paint);

    //为画笔设置DST_OUT模式,即显示目的颜色以外的颜色
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    //将目的图层画到主图层上,产生混合效果
    canvas.drawBitmap(mDstB, 0, 0, paint);

    //返回到之前保存的图层,开始渲染
    canvas.restoreToCount(sc);

最终显示出来的效果为黑色半透明上有一个镂空的圆形。可以用于App中常见的蒙层引导。

猜你喜欢

转载自blog.csdn.net/joye123/article/details/76796604