ColorFilter主要用来处理颜色,这里将讲解它的三个子类,ColorMatrixColorFilter,
LightingColorFilter以及PorterDuffColorFilter。
这个类主要是使用matrix也就是矩阵对颜色做运算,矩阵的形态如下:
颜色值和该矩阵的换算关系如下:
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的范围内。
看了上面的说明可能不太清晰,这里再看看例子,
上面有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,这样一来就变为了黑白图片。
明白了上面颜色运算的规则,就可以自己更改矩阵的值从而达到想要的效果。这里举一个示例
LightingColorFilter是上面ColorMatrixColorFilter的一个简化版本,构造函数也比较简单:
public LightingColorFilter(int mul, int add)
mul代表multiply,也就是乘法
add代表加法,也就是颜色偏移量
那么这里将怎么计算颜色值呢,其实跟上面矩阵的方式差不多。这里两个参数都是int类型,所以每8位被分别分解为RGB对应的值来做乘法和加法。
先来看一个 例子:
看一下代码实现:
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 = color*mul/255+add (计算结果大于等于255都指定为255)
其中color可以为RGB三种通道中的一种,mul和add分别为通道对应的值。假设R通道的值就为
R=R*0x88/0xff+0
0x88/0xff肯定是小于1的,所以颜色变暗了。
第三张图的mul值和第二张相同,但是由于第三张图的add值比较大,所以反而比第一张图还亮。
看他的构造函数
public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode)
srcColor源颜色,
mode是色彩的混合模式,这里的混合模式我们在后面再详细讲解,这里简单看一个示例。
看看代码实现:
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值就能得到不同的效果。各个值不同的效果我们在后面的篇幅中详细讲解。