Paint 的ColorFilter(颜色过滤器)和 XFermode(图层混合模式)

Paint 的ColorFilter(颜色过滤器)和 XFermode(图层混合模式)

ColorFilter-颜色过滤器

顾名思义就是 Paint 画笔的颜色过滤功能。通过 setColorFilter(ColorFilter filter) 方法进行设置,该方法传入了一个 ColorFilter 对象,我们来看下这个是个嘛东东。

/**
 * A color filter can be used with a {@link Paint} to modify the color of
 * each pixel drawn with that paint. This is an abstract class that should
 * never be used directly.
 * 
 * 原意:一个可以作用于 Paint 的颜色过滤器,可以用来修改每一个像素的颜色。
 * 这是一个抽象类,不能被直接使用
 * 
 */
public class ColorFilter {}

注释发现这是一个抽象类(抽象类你不写 abstract ,这么懒么。。),查看这个假的抽象类 ColorFilter 有以下三个子类,我们分别来看。

  • 光照色彩过滤器:LightingColorFilter
  • 混排颜色过滤器滤器:PorterDuffColorFilter
  • 颜色矩阵颜色过滤器:ColorMatrixColorFilter

LightingColorFilter(光照色彩过滤器)

构造函数:
LightingColorFilter(@ColorInt int mul, @ColorInt int add)

其参数 muladd 都是16进制的色彩值0xAARRGGBB,mul 用来和目标像素相乘,add 用来和目标像素相加。具体计算逻辑如下:

R' = R * colorMultiply.R + colorAdd.R
G' = G * colorMultiply.G + colorAdd.G
B' = B * colorMultiply.B + colorAdd.B

在这里插入图片描述

你说啥?有点懵逼?来个例子就清楚了,比如我们要去掉每个像素中的绿色,就可以传入 ( mul = 0xff00ff , add = 0x000000) 。脑阔疼,这玩意咋算。

假如原像素 0xabcdef 
mul = 0xff00ff
add = 0x000000
其他颜色不变,将绿色至为0,则:
R' = 0xab * mul.0xff + add.0x00
G' = 0xcd * mul.0x00 + add.0x00 = 0
B' = 0xef * mul.0xff + add.0x00
这样,绿色就无情的被抹掉了。下面即为实现效果

在这里插入图片描述
在这里插入图片描述

PorterDuffColorFilter(混排颜色过滤器滤器)

通过其构造函数,发现接受两个参数,分别是混合的颜色 color 和混合模式 mode

PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode)

其中 color 值为16进制的色彩值0xAARRGGBB。而混合模式系统一共提供了18种混合模式,每个混合模式都有自己的计算方法,每种模式对应的功能我们在 XFermode(图层混合模式) 中已经讲解。具体用法如下:

PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN);
mPaint.setColorFilter(porterDuffColorFilter);
invalidate();

ColorMatrixColorFilter(颜色矩阵颜色过滤器)

通过 ColorMatrix 颜色矩阵来操作目标像素,具体 ColorMatrix 可以看 官网解析。具体使用如下

float[] colorMatrix = {
             1,0,0,0,0,   //red
             0,1,0,0,0,   //green
             0,0,1,0,0,   //blue
             0,0,0,1,0    //alpha
     }
ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
mPaint.setColorFilter(colorMatrixColorFilter);
invalidate();

下面贴上全部代码:

package com.wuba.demo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import android.view.View;

/**
 * Author silence.
 * Time:2019-08-08.
 * Desc:
 */
public class PaintColorFilter extends View {

    private Paint mPaint;
    private Bitmap mBitmap;

    public PaintColorFilter(Context context) {
        this(context,null);
    }

    public PaintColorFilter(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public PaintColorFilter(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 2;
        mBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.baybay,options);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.drawBitmap(mBitmap,0,0,mPaint);
    }

    public void reset(){
        mPaint.reset();
        invalidate();
    }

    public void lightingColorFilter( int mul,  int add){
        /**
         * 光照色彩过滤器
         * LightingColorFilter(@ColorInt int mul, @ColorInt int add)
         * mul 和 add 都是16进制的色彩值0xAARRGGBB,mul 用来和目标像素相乘,add 用来和目标像素相加
         * R' = R * colorMultiply.R + colorAdd.R
         * G' = G * colorMultiply.G + colorAdd.G
         * B' = B * colorMultiply.B + colorAdd.B
         * eg: 去掉绿色。原像素 0xabcdef , mul 0xff00ff , add 0x000000
         *  其他颜色不变,将绿色至为0
         * R' = 0xab * mul.0xff + add.0x00
         * G' = 0xcd * mul.0x00 + add.0x00 = 0
         * B' = 0xef * mul.0xff + add.0x00
         */
        LightingColorFilter lightingColorFilter = new LightingColorFilter(mul,add);
        mPaint.setColorFilter(lightingColorFilter);
        invalidate();
    }

    public void porterDuffColorFilter(int color){
        /**
         * 混排颜色过滤器滤器
         * PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode)
         * color:具体的颜色值,如Color.RED
         * mode:指定PorterDuff.Mode 混合模式
         */
        PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.DARKEN);
        mPaint.setColorFilter(porterDuffColorFilter);
        invalidate();
    }

    public void colorMatrixColorFilter(float[] colorMatrix){
        /**
         * 颜色矩阵颜色过滤器
         * ColorMatrixColorFilter(@NonNull float[] array)
         * array:矩阵数组
         * eg:float[] colorMatrix = {
         *             1,0,0,0,0,   //red
         *             0,1,0,0,0,   //green
         *             0,0,1,0,0,   //blue
         *             0,0,0,1,0    //alpha
         *     }
         */
        ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
        mPaint.setColorFilter(colorMatrixColorFilter);
        invalidate();
    }



}

XFermode-图层混合模式

将绘制图形中的像素与 Canvas 中的对应位置的像素按照一定规则进行混合,形成新的像素值,从而更新 Canvas 中的颜色值。系统为我们提供了18中混合模式:PorterDuff.Mode 官方文档

    public enum Mode {
        //绘制内容不提交到 canvas 画布中
        CLEAR       (0),
        //显示上层绘制图像
        SRC         (1),
        //显示下层绘制图像
        DST         (2),
        //正常绘制显示,上下图层 叠盖绘制
        SRC_OVER    (3),
        //上下层都显示,下层居上显示
        DST_OVER    (4),
        //取两层绘制交集,显示上层
        SRC_IN      (5),
        //取两层绘制交集,显示下层
        DST_IN      (6),
        //取上层绘制非交集部分,交集部分变透明
        SRC_OUT     (7),
        //取下层绘制非交集部分,交集部分变透明
        DST_OUT     (8),
        //取上层交集部分与下层非交集部分
        SRC_ATOP    (9),
        //取下层交集部分与上层非交集部分
        DST_ATOP    (10),
        //取去除两个图层交集部分
        XOR         (11),
        //取两个图层全部区域,交集部分颜色加深
        DARKEN      (16),
        //取两个图层全部区域,交集部分颜色点亮
        LIGHTEN     (17),
        //取两个图层交集部分,颜色叠加
        MULTIPLY    (13),
        //取两个图层全部区域,交集部分滤色
        SCREEN      (14),
        //取两个图层全部区域,交集部分饱和度相加
        ADD         (12),
        //取两个图层全部区域,交集部分叠加
        OVERLAY     (15);

    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值