在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可以控製圖像的顏色效果。顏色分量矩陣C2所示。
圖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 圖片處理效果