# Android Matrix矩阵详解

Android中有两个比较重要的矩阵，ColorMatrix和Matrix。ColorMatrix用来改变bitmap的颜色和透明度，Matrix用来对bitmap平移、缩放、错切。

## ColorMatrix(色彩矩阵)

Android中Bitmap色彩用了一个[R, G, B, A]，4*1的矩阵来保存。

ColorMatrix的默认矩阵如下图所示

### 黑白图片

    private Bitmap handleColorMatrix(){
Canvas canvas = new Canvas(mTempBmp); // 创建一个画布
Paint paint = new Paint(); // 新建paint
paint.setAntiAlias(true); //抗锯齿
//黑白
ColorMatrix colorMatrix = new ColorMatrix(new float[]{
0.213f, 0.715f, 0.072f, 0, 0,
0.213f, 0.715f, 0.072f, 0, 0,
0.213f, 0.715f, 0.072f, 0, 0,
0,       0,    0, 1, 0,
});
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));// 设置颜色变换效果
canvas.drawBitmap(mOriginBmp, 0, 0, paint);
return mTempBmp;
}

### 色彩偏移和缩放

    ColorMatrix colorMatrix = new ColorMatrix(new float[]{
1, 0, 0, 0, 20,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
});

    ColorMatrix colorMatrix = new ColorMatrix(new float[]{
1, 0, 0, 0, 0,
0, 1.2f, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
});

       /**
* Set this colormatrix to scale by the specified values.
*/
public void setScale(float rScale, float gScale, float bScale,
float aScale) {
final float[] a = mArray;

for (int i = 19; i > 0; --i) {
a[i] = 0;
}
a[0] = rScale;
a[6] = gScale;
a[12] = bScale;
a[18] = aScale;
}

### 色彩饱和度

ColorMatrix提供了一个setSaturation通过改变对角线上的比例来改变饱和度。

    /**
* Set the matrix to affect the saturation of colors.
*
* @param sat  饱和度的值，取值0,1
*/
public void setSaturation(float sat) {
reset();
float[] m = mArray;

final float invSat = 1 - sat;
final float R = 0.213f * invSat;
final float G = 0.715f * invSat;
final float B = 0.072f * invSat;

m[0] = R + sat; m[1] = G;       m[2] = B;
m[5] = R;       m[6] = G + sat; m[7] = B;
m[10] = R;      m[11] = G;      m[12] = B + sat;
}

### 色彩旋转

    public void setRotate(int axis, float degrees) {
reset();
double radians = degrees * Math.PI / 180d;
float cosine = (float) Math.cos(radians);
float sine = (float) Math.sin(radians);
switch (axis) {

case 0:  // 围绕红色轴旋转
mArray[6] = mArray[12] = cosine;
mArray[7] = sine;
mArray[11] = -sine;
break;

case 1:   // 围绕绿色轴旋转
mArray[0] = mArray[12] = cosine;
mArray[2] = -sine;
mArray[10] = sine;
break;

case 2:  // 围绕蓝色色轴旋转
mArray[0] = mArray[6] = cosine;
mArray[1] = sine;
mArray[5] = -sine;
break;
default:
throw new RuntimeException();
}
}

## Matrix(矩阵)

setTranslate//设置平移矩阵
setScale //设置缩放矩阵
setRotate //设置旋转矩阵。
setSkew //设置错切矩阵
...

preTranslate(float dx, float dy) //先乘平移矩阵，M' = M * T(dx, dy)
preScale(float sx, float sy) //先乘缩放矩阵，M' = M * S(sx, sy)
preRotate(float degrees, float px, float py)//先乘旋转矩阵，M' = M * R(degrees, px, py)
preSkew(float kx, float ky)//先乘错切矩阵，M' = M * K(kx, ky)
...

postTranslate(float dx, float dy) //后乘平移矩阵，M' = T(dx, dy) * M
postScale(float sx, float sy) //后乘缩放矩阵，M' = S(sx, sy) * M
postRotate(float degrees, float px, float py)//后乘旋转矩阵，M' = R(degrees, px, py) * M
postSkew(float kx, float ky)//后乘错切矩阵，M' = K(kx, ky) * M
...