ColorMatrix,色彩矩阵,是Android中图片色彩处理的关键类,通过它可以实现图片的各种酷炫效果,学习色彩矩阵之前先来学习一下矩阵.
一:矩阵的来源:
我们都知道矩阵的形式,
但是矩阵的来源是什么呢,其实矩阵最早来自于方程组的系数及常数所构成的方阵。
比如:
对应的矩阵阵列:
这个矩阵阵列有什么用呢?不要小看了这个矩阵,这里矩阵决定着这个方程组是否有解,以及如果有 解,解是什么。
也就是说利用矩阵可以对线性方程组进行方便快速地求解。
二:矩阵的运算
矩阵的加法:
矩阵的乘法:
加法运算条件必须是同型矩阵,乘法条件是A是m×n矩阵,B是n×p矩阵。
了解了这些基本的矩阵概念,再来看Android中的ColorMatrix。
三.ColorMatrix
大家都知道在Android图片中采用ARGB来表示颜色,图片中每一个点都有自己的RGBA值,将这个RGBA值当成只有一列的矩阵,让这个矩阵乘上另外一个矩阵得到变化,以改变图片颜色,这里的另一个矩阵就是ColorMatrix。
首先,根据矩阵乘法,我们觉得一个4*4的ColorMatrix就可以了,
比如:
但是为什么最后ColorMatrix用了4*5的矩阵。原因看图:
e,j,o,t是没有系数的,当我们想增加某一个属性而不影响其他时,只需要修改e,j,o,t的值。所以:
•第一行的 abcde 用来决定新的颜色值中的R——红色
•第二行的 fghij 用来决定新的颜色值中的G——绿色
•第三行的 klmno 用来决定新的颜色值中的B——蓝色
•第四行的 pqrst 用来决定新的颜色值中的A——透明度
•矩阵A中第五列——ejot 值分别用来决定每个分量中的 offset ,即偏移量
•色值的区间为[0,255]
四.使用
1.去除红色效果:
Bitmap bitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
//去掉红色
mMatrix = new float[]{
0, 0, 0, 0, 0,//红色
0, 1, 0, 0, 0,//绿色
0, 0, 1, 0, 0,//蓝色
0, 0, 0, 1, 0,//透明色
};
//色彩矩阵
ColorMatrix colorMatrix = new ColorMatrix(mMatrix);
//画板
Canvas canvas = new Canvas(bitmap);
//画笔
Paint paint = new Paint();
//给画笔设置颜色过滤器,里面使用色彩矩阵
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
//将mBitmap临摹到bitmap上,使用含有色彩矩阵的画笔
canvas.drawBitmap(mBitmap, 0, 0, paint);
mIvNew.setImageBitmap(bitmap);
2.去掉绿色效果:
Bitmap bitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
mMatrix = new float[]{
1, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
};
ColorMatrix colorMatrix = new ColorMatrix(mMatrix);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(mBitmap, 0, 0, paint);
mIvNew.setImageBitmap(bitmap);
3.去掉蓝色效果:
Bitmap bitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
mMatrix = new float[]{
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 1, 0,
};
ColorMatrix colorMatrix = new ColorMatrix(mMatrix);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(mBitmap, 0, 0, paint);
mIvNew.setImageBitmap(bitmap);
4.灰度特效:
Bitmap bitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
mMatrix = new float[]{
0.33f, 0.59f, 0.11f, 0, 0,
0.33f, 0.59f, 0.11f, 0, 0,
0.33f, 0.59f, 0.11f, 0, 0,
0, 0, 0, 1, 0,
};
ColorMatrix colorMatrix = new ColorMatrix(mMatrix);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(mBitmap, 0, 0, paint);
mIvNew.setImageBitmap(bitmap);
5.图像反转:
Bitmap bitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
mMatrix = new float[]{
-1, 0, 0, 1, 1,
0, -1, 0, 1, 1,
0, 0, -1, 1, 1,
0, 0, 0, 1, 0,
};
ColorMatrix colorMatrix = new ColorMatrix(mMatrix);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(mBitmap, 0, 0, paint);
mIvNew.setImageBitmap(bitmap);
6.封装的api:
除了直接设置矩阵的值外,该类还封装了一些API来快速调整矩阵参数,如:通过setRotate()方法设置色调、setSaturation()方法设置饱和度、setScale()方法设置亮度。这些方法使用起来很简单
// 创建副本,用于将处理过的图片展示出来而不影响原图,Android系统也不允许直接修改原图
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
// 修改色调,即色彩矩阵围绕某种颜色分量旋转
ColorMatrix rotateMatrix = new ColorMatrix();
// 0,1,2分别代表像素点颜色矩阵中的Red,Green,Blue分量
rotateMatrix.setRotate(0,rotate);
rotateMatrix.setRotate(1,rotate);
rotateMatrix.setRotate(2,rotate);
// 修改饱和度
ColorMatrix saturationMatrix = new ColorMatrix();
saturationMatrix.setSaturation(saturation);
// 修改亮度,即某种颜色分量的缩放
ColorMatrix scaleMatrix = new ColorMatrix();
// 分别代表三个颜色分量的亮度
scaleMatrix.setScale(scale,scale,scale,1);
//将三种效果结合
ColorMatrix imageMatrix = new ColorMatrix();
imageMatrix.postConcat(rotateMatrix);
imageMatrix.postConcat(saturationMatrix);
imageMatrix.postConcat(scaleMatrix);
paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
canvas.drawBitmap(bitmap,0,0,paint);