在Android中,對圖像進行顏色方面的處理,如黑白老照片、泛黃舊照片、高對比度、低飽和度等效果,都可以通過使用顏色矩陣(ColorMatrix)來實現。
1.顏色矩陣(ColorMatrix)介紹
顏色矩陣M是一個5*4的矩陣,如圖1所示。在Android中,顏色矩陣M是以一維數組m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式進行存儲的。
圖1 顏色矩陣M
在一張圖片中,圖像的RGBA(紅色、綠色、藍色、透明度)值決定了該圖片所呈現出來的顏色效果。而圖像的RGBA值則存儲在一個5*1的顏色分量矩陣C中,由顏色分量矩陣C可以控制圖像的顏色效果。顏色分量矩陣C如圖2所示。
圖2 顏色分量矩陣C
要想改變一張圖片的顏色效果,只需要改變圖像的顏色分量矩陣即可。通過顏色矩陣可以很方便的修改圖像的顏色分量矩陣。假設修改后的圖像顏色分量矩陣為C1,則有如圖3所示的顏色分量矩陣計算公式。
圖3 顏色分量矩陣計算公式
由此可見,通過顏色矩陣修改了原圖像的RGBA值,從而達到了改變圖片顏色效果的目的。並且,通過如圖3所示的運算可知,顏色矩陣M的第一行參數abcde決定了圖像的紅色成分,第二行參數fghij決定了圖像的綠色成分,第三行參數klmno決定了圖像的藍色成分,第四行參數pqrst決定了圖像的透明度,第五列參數ejot是顏色的偏移量。
通常,改變顏色分量時可以通過修改第5列的顏色偏移量來實現,如圖4所示的顏色矩陣M1,通過計算后可以得知該顏色矩陣的作用是使圖像的紅色分量和綠色分量均增加100,這樣的效果就是圖片泛黃(因為紅色與綠色混合后得到黃色)。
圖4 顏色矩陣M1
除此之外,也可以通過直接對顏色值乘以某一系數而達到改變顏色分量的目的。如圖5所示的顏色矩陣M2,將綠色分量放大了2倍,這樣的效果就是圖片泛綠色。
圖5 顏色矩陣M2
2.圖像顏色處理實例
了解了顏色矩陣的工作原理之后,我們就可以使用顏色矩陣對圖片進行處理了。
2.1主界面布局
在主界面布局中,首先需要自定義一個View控件,用來顯示圖片的處理效果。然后還需要二十個EditText控件,用來輸入顏色矩陣的值。最后還需要一個Button控件,用來提交圖片處理請求。完成后的主界面布局效果如圖6所示。
圖6 主界面布局
其中,主界面最頂端的圖片就是我們要進行顏色處理的原始圖片。在二十個EditText控件中,我們設置了顏色矩陣的初始值為{1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0}。自定義的View控件可以參照下面的方法在xml布局文件中進行定義。
1 <!-- 自定義的View控件 --> 2 <com.example.android_colormatrix.MyView 3 android:id="@+id/myView" 4 android:layout_width="480dp" 5 android:layout_height="180dp" > 6 </com.example.android_colormatrix.MyView>
需要注意的是,自定義的控件一定要包含完整的包名。通過以上代碼可以看出,該自定義控件是在MyView中進行實現的。下面就來看看MyView中是如何實現自定義的View控件的。
2.2自定義View控件的實現
要實現自定義的View類,其實也很簡單,只需要讓MyView繼承View類並重寫View類的OnDraw()方法即可。
在OnDraw()方法中,我們需要做五件事情:
(1)新建Paint畫筆對象,用於描畫。
(2)新建ColorMatrix顏色矩陣對象,用於儲存顏色矩陣。
(3)設置ColorMatrix顏色矩陣的值。
(4)設置Paint畫筆的顏色過濾器。
(5)使用Paint畫筆描畫,輸出Bitmap圖像。
上述五個步驟的具體實現代碼如下:
1 /** 2 * Function : 描畫函數 3 * Param : canvas畫布對象 4 * Author : 博客園-依舊淡然 5 */ 6 public void onDraw(Canvas canvas) { 7 8 Paint mPaint = new Paint(); //新建畫筆對象 9 canvas.drawBitmap(mBitmap, 0, 0, mPaint); //描畫(原始圖片) 10 11 ColorMatrix mColorMatrix = new ColorMatrix(); //新建顏色矩陣對象 12 mColorMatrix.set(array); //設置顏色矩陣的值 13 mPaint.setColorFilter(new ColorMatrixColorFilter(mColorMatrix)); //設置畫筆顏色過濾器 14 canvas.drawBitmap(mBitmap, 0, 0, mPaint); //描畫(處理后的圖片) 15 }
其中,mBitmap就是我們需要處理的圖片對象。array數組則用於儲存我們從EditText控件中獲取的用戶輸入值。那么如何將EditText控件中的用戶輸入值儲存到array數組中呢?可以使用如下的方法。
1 /** 2 * Function : 從EditText中獲取輸入值儲存到array數組中 3 * Param : 4 * Author : 博客園-依舊淡然 5 */ 6 public void getValues() { 7 for (int i = 0; i < 20; i++) { 8 array[i] = Float.valueOf(mEditText[i].getText().toString()); 9 } 10 }
2.3實例效果
運行程序后,在如圖6所示的界面中輸入顏色矩陣的值,點擊“變換”按鈕后,就可以看到不同的圖片處理效果了。
如果我們將顏色矩陣的紅色分量放大2倍,則可以得到如圖7所示的泛紅的圖片效果。
圖7 泛紅的圖片效果
除此之外,我們還可以利用顏色矩陣很容易的實現高對比度、高飽和度、色相變換等圖片處理效果,如圖8所示。
圖8 圖片處理效果
相關資料:
Android圖片處理(Matrix、ColorMatrix)
http://www.cnblogs.com/leon19870907/articles/1978065.html