文章目录

  • 1、概述
  • 2、ColorMatrixColorFilter
  • 3、 LightingColorFilter
  • 4、PorterDuffColorFilter


1、概述

ColorFilter主要用来处理颜色,这里将讲解它的三个子类,ColorMatrixColorFilter,
LightingColorFilter以及PorterDuffColorFilter。

2、ColorMatrixColorFilter

这个类主要是使用matrix也就是矩阵对颜色做运算,矩阵的形态如下:

ColorFilter 简介_Red


颜色值和该矩阵的换算关系如下:

RGB和Alpha的终值计算方法如下:
Red通道终值= a[0] * srcR + a[1] * srcG + a[2] * srcB + a[3] * srcA + a[4]
Green通道终值= a[5] * srcR + a[6] * srcG + a[7] * srcB + a[8] * srcA + a[9]
Blue通道终值= a[10] * srcR + a[11] * srcG + a[12] * srcB + a[13] * srcA + a[14]
Alpha通道终值= a[15]*srcR+a[16]*srcG + a[17] * srcB + a[18] * srcA + a[19]

备注: srcR为原图Red通道值,srcG为原图Green通道值,srcB为原图Blue通道值,srcA为原图Alpha通道值。
每个通道的源值和终值都在0到255的范围内。即使计算结果大于255或小于0,值都将被限制在0到255的范围内。

看了上面的说明可能不太清晰,这里再看看例子,

ColorFilter 简介_构造函数_02


上面有3张图片,其实是同一个图片绘制的,只是使用了不同的ColorMatrixColorFilter,最后面一张是完全黑白的。

看看代码的实现:

private final static float[] MATRIX = new float[] {
            0.5f, 0, 0, 0, 0,
            0, 0.5f, 0, 0, 0,
            0, 0, 0.5f, 0, 0,
            0, 0, 0, 1, 0 };

Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.home);

canvas.drawBitmap(bitmap, 100, 0, paint);

ColorMatrixColorFilter filter = new ColorMatrixColorFilter(MATRIX);
paint.setColorFilter(filter);
canvas.drawBitmap(bitmap, 100, 500, paint);


ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(bitmap, 100, 1000, paint);

MATRIX中的值是0.5使得R,G,B通道的值都减半了,所以第二张图看起来暗了很多
第三张图使用了ColorMatrix,并且使用colorMatrix.setSaturation(0)将饱和度设置为了0,这样一来就变为了黑白图片。

明白了上面颜色运算的规则,就可以自己更改矩阵的值从而达到想要的效果。这里举一个示例

3、 LightingColorFilter

LightingColorFilter是上面ColorMatrixColorFilter的一个简化版本,构造函数也比较简单:

public LightingColorFilter(int mul, int add)

mul代表multiply,也就是乘法
add代表加法,也就是颜色偏移量

那么这里将怎么计算颜色值呢,其实跟上面矩阵的方式差不多。这里两个参数都是int类型,所以每8位被分别分解为RGB对应的值来做乘法和加法。

先来看一个 例子:

ColorFilter 简介_Red_03


看一下代码实现:

Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.home);

canvas.drawBitmap(bitmap, 100, 0, paint);

LightingColorFilter filter = new LightingColorFilter(0x888888, 0x000000);
paint.setColorFilter(filter);
canvas.drawBitmap(bitmap, 100, 500, paint);

LightingColorFilter filter2 = new LightingColorFilter(0x888888, 0x555555);
paint.setColorFilter(filter2);
canvas.drawBitmap(bitmap, 100, 1000, paint);

看第二张图片的ColorFilter构造new LightingColorFilter(0x888888, 0x000000);
其中mul为0x888888,那么RGB通道对应的mul值都为88,add为0x000000则对应的偏移量都为0。第二张图变暗了,基本可以看出计算方法。
color = colormul/255+add (计算结果大于等于255都指定为255)
其中color可以为RGB三种通道中的一种,mul和add分别为通道对应的值。假设R通道的值就为
R=R
0x88/0xff+0
0x88/0xff肯定是小于1的,所以颜色变暗了。

第三张图的mul值和第二张相同,但是由于第三张图的add值比较大,所以反而比第一张图还亮。

4、PorterDuffColorFilter

看他的构造函数

public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode)

srcColor源颜色,
mode是色彩的混合模式,这里的混合模式我们在后面再详细讲解,这里简单看一个示例。

ColorFilter 简介_Red_04


看看代码实现:

Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.home);

canvas.drawBitmap(bitmap, 100, 0, paint);

PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.MULTIPLY);
paint.setColorFilter(filter);
canvas.drawBitmap(bitmap, 100, 500, paint);

这里PorterDuffColorFilter的两个参数分别是Color.BLUE以及PorterDuff.Mode.MULTIPLY

先不要纠结PorterDuff.Mode.MULTIPLY的含义,这里主要是将Color.BLUE提供的蓝色和原图进行一定的合并运算。就得到了上面的效果,那么传入不同PorterDuff.Mode值就能得到不同的效果。各个值不同的效果我们在后面的篇幅中详细讲解。