Android圖片處理:顏色矩陣和坐標變換矩陣
UI開發過程中,我們經常需要對圖片進行處理,常見的如貼圖,復雜一些的還有位置變換、旋轉、濾鏡特效等,下面簡單介紹一下關于圖片處理的一些基本知識和原理。
1 基本概念
對 于圖片的處理,最常使用到的數據結構是Bitmap,它包含了一張圖片所有的數據,這些數據數據包括那些內容呢?簡單說來就是由點陣和顏色值組成的,所謂 點陣就是一個在概念上是Width * Height的矩陣,每一個元素對應著圖片的一個像素,也就是說,點陣保存著圖片的空間位置信息;而顏色值即ARGB,分別對應透明度、紅、綠、藍這四個 通道分量,每個通道用8比特定義,所以一個顏色值就是一個int整型,可以表示256*256*256種顏色值。
Android 中我們常用到這么幾個常量:ARGB_8888、ARGB_4444、RGB_565。這幾個常量其實就是告訴系統如何對圖片的顏色值進行處理,例如 ARGB_8888是告訴系統透明度、R、G、B在顏色值中分別用8bit表示,這時顏色值為32bit,這樣的定義能夠表示最多的顏色值,圖片質量也是 最好的;ARGB_4444則是每個通道用4bit表示,這樣顏色值只用16bit,節省了空間,但是卻只能表示16*16*16種顏色,也就是說圖片很 失去很多彩色信息;RGB_565類型的顏色值同樣是16bit,但是它丟棄了透明度信息,可以表示32*64*32種顏色值。
2 顏色矩陣
顏色矩陣是一個5*4的矩陣,用來對圖片顏色值進行處理。定義顏色矩陣和顏色值如下如下:
進行如下矩陣運算:
結果R為4*1的矩陣,這個矩陣就是新的顏色值,R中每個通道的值分別如下:
R’ = a*R + b*G + c*B + d*A + e;
G’ = f*R + g*G + h*B + i*A + j;
B’ = k*R + l*G + m*B + n*A + o;
A’ = p*R + q*G + r*B + s*A + t;
這樣看起來或許很抽象,很難理解顏色矩陣和結果R直接的關系,我們假設顏色矩陣值如下所示:
那么結果為:
R’ = R;
G’ = G;
B’ = B;
A’ = A;
也就是說,新的顏色值跟原先的一樣!再看一個例子,顏色矩陣取值為:
結果為:
R’ = R + 100;
G’ = G + 100;
B’ = B;
A’ = A;
新的顏色值中,紅色通道值和綠色通道值分別增加了100,此時圖片會泛黃(因為R + G = Yellow)。
從上面的幾個例子我們很容易就能明白顏色矩陣中的每個分量(每一列)的意義:
第一行決定紅色,
第二行決定綠色,
第三行決定藍色,
第四行決定了透明度,
第五列是顏色的偏移量。
至此我們應該能理解如何通過顏色矩陣來改變顏色值的各個分量了。
下面是用于Android的一段代碼,用于將圖片處理成泛黃的效果:
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; }