从矩阵来看颜色变换


开篇

之前从矩阵的角度分析了平移,旋转,缩放,对称的变换,文章在从矩阵来看Android中的一些动画变换

在android中,图片的对象主要是bitmap,它是由点阵和颜色值组成的。
1、点阵是一个图片宽*图片高的矩阵,矩阵中的每一个元素对应着图片的一个像素。根据点阵可以计算出图片占用的内存大小。

1
2
3
4
ALPHA_8:  每个像素占用1byte内存
ARGB_4444: 每个像素占用2byte内存
ARGB_8888: 每个像素占用4byte内存
RGB_565: 每个像素占用2byte内存
1
2
3
4
5
6
图片占用内存 = 图片高度显示像素 * 图片宽度显示像素 * 每个像素占用的内存大小

显示像素 = 图片实际像素 * 手机density / 图片density

假设有一张长宽为800*600、通道为ARGB_8888的图片,那么它占的内存为:
800*600*4byte = 1875KB = 1.83M

2、颜色值,是由三原色和透明度决定的,即ARGB,分别对应着四个颜色通道,每个通道用8byte定义,所以一个颜色值就是一个int整型,可以表示256x256x256种颜色值。

在android中和颜色有关的几个常量:ARGB_8888、ARGB_4444、RGB_565。
ARGB_8888,是图片的透明度、R、G、B的每个颜色值占8bit,可以表示256x256x256种颜色,也就是可以表示最多的颜色值,图片质量也是最好的。

ARGB_4444,是图片的透明度、R、G、B的每个颜色值占4bit,可以表示16x16x16种颜色,相对ARGB_8888,它节省了空间,却失去了很多色彩。

RGB_565,它只有R、G、B三个颜色通道,没有透明度通道,可以表达32x64x32种颜色。

四个颜色通道是由一个4x5的变换矩阵控制的。

颜色矩阵变换

推导

所以,可以知道,红色通道由第一行控制。
绿色通道由第二行控制。
蓝色通道由第三行控制。
透明度通道由第四行控制。
另外的,第五列是每个通道的偏移量。注意倍数和相加的影响,每个通道最后的值不应该大于256.

在android中,有一个和颜色矩阵相关的android.graphics.Matrix类,该类中有与颜色变换相关的方法。

方法

关于Matrix方法的使用这里就不详细讲了。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static Bitmap testBitmap(Bitmap bitmap)
{
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.RGB_565);

Canvas canvas = new Canvas(output);

Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
float[] array = {1,0,0,0,100,
0,1,0,0,100,
0,0,1,0,0,
0,0,0,1,0};
cm.set(array);
paint.setColorFilter(new ColorMatrixColorFilter(cm));

canvas.drawBitmap(bitmap, 0, 0, paint);
return output;
}

JNI图片压缩

在上面提到过一张图片占用多大内存的计算,现在我们的手机拍出来的照片占的内存越来越大,所以在开发的过程中,我们就很有必要对图片压缩后再上传。而比较好的压缩方法是JNI压缩。

github地址