天天看點

android - ColorMatrix詳解使用示例

自定義View系列目錄

涉及方法

類别 API 描述
旋轉 setRotate 設定(非輸入軸顔色的)色調
飽和度 setSaturation 設定飽和度
縮放 setScale 三原色的取值的比例
設定 set、setConcat 設定顔色矩陣、兩個顔色矩陣的乘積
重置 reset 重置顔色矩陣為初始狀态
矩陣運算 preConcat、postConcat 顔色矩陣的前乘、後乘

一、顔色矩陣

顔色矩陣是一個用來表示三原色和透明度的4x5的矩陣,表示為一個數組的形式

[ a, b, c, d, e,

f, g, h, i, j,

k, l, m, n, o,

p, q, r, s, t ]
           

顔色矩陣計算

一個顔色則使用

[R, G, B, A]

的方式進行表示,是以矩陣與顔色的計算方式則為

android - ColorMatrix詳解使用示例

從上述的公式可以看出,顔色矩陣的功能劃分如下

  • a, b, c, d, e

     表示三原色中的紅色
  • f, g, h, i, j

     表示三原色中的綠色
  • k, l, m, n, o

     表示三原色中的藍色
  • p, q, r, s, t

     表示顔色的透明度
  • 第五列用于表示顔色的偏移量

使用示例

首先我們在不改變初始矩陣的情況下,來看一下圖檔的效果

private ColorMatrix mColorMatrix;

private Paint mPaint;

private Bitmap oldBitmap;

mColorMatrix = new ColorMatrix();

mPaint = new Paint();

// 設定畫筆的顔色過濾器

mPaint.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));

Log.d("TAG", Arrays.toString(mColorMatrix.getArray()));

// 建立Bitmap

oldBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.header);

// 在畫布上顯示圖檔

canvas.drawBitmap(oldBitmap,0,0,mPaint);

// Log

TAG: [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]
           
android - ColorMatrix詳解使用示例

初始矩陣

現在我們建立一個矩陣,使用set方法來使用這個矩陣,改變圖檔的顔色

mColorMatrix.set(new float[]{

1,0.5f,0,0,0

,0,1,0,0,0

,0,0,1,0,0

,0,0,0,1,0});
           
android - ColorMatrix詳解使用示例

紅矩陣

二、常用方法

1、旋轉

API如下:

/**

* 用于色調的旋轉運算

* axis=0 表示色調圍繞紅色進行旋轉

* axis=1 表示色調圍繞綠色進行旋轉

* axis=2 表示色調圍繞藍色進行旋轉

*/

public void setRotate(int axis, float degrees)
           

三原色坐标系

android - ColorMatrix詳解使用示例

a、圍繞紅色軸旋轉

我們可以根據三原色來建立一個三維向量坐标系,當圍繞紅色旋轉時,我們将紅色虛化為一個點,綠色為橫坐标,藍色為縱坐标,旋轉θ°。

坐标系示例

android - ColorMatrix詳解使用示例

紅色坐标系

根據平行四邊形法則R、G、B、A各值計算結果:

android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例

矩陣表示:

android - ColorMatrix詳解使用示例

b、圍繞綠色軸旋轉

綠色虛化為一個點,藍色為橫坐标軸,紅色為縱坐标軸,旋轉θ°。

坐标系示例

android - ColorMatrix詳解使用示例

綠色坐标系

根據平行四邊形法則R、G、B、A各值計算結果:

android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例

矩陣表示:

android - ColorMatrix詳解使用示例

c、圍繞藍色軸旋轉

藍色虛化為一個點,紅色為橫坐标軸,綠色為縱坐标軸,旋轉θ°。

坐标系示例

android - ColorMatrix詳解使用示例

藍色坐标系

根據平行四邊形法則R、G、B、A各值計算結果:

android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例

矩陣表示:

android - ColorMatrix詳解使用示例

使用示例

這裡設定色調圍繞紅色軸旋轉90°

// 旋轉綠色、藍色

mColorMatrix.setRotate(0,90);

// Log

D/TAG: [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.371139E-8, 1.0, 0.0, 0.0, 0.0, -1.0, -4.371139E-8, 0.0, 0.0,

0.0, 0.0, 0.0, 1.0, 0.0]
           

從Log中我們可以看出,其結果也驗證了我們的上述理論,圖檔效果如下:

android - ColorMatrix詳解使用示例

旋轉矩陣

2、縮放

API如下:

/**

* rScale 表示紅色的數值的縮放比例

* gScale 表示綠色的數值的縮放比例

* bScale 表示藍色的數值的縮放比例

* aScale 表示透明度的數值的縮放比例

*/

public void setScale(float rScale, float gScale, float bScale,float aScale)
           

R、G、B、A各值計算結果:ColorMatrix的縮放方法,其實就是根據矩陣的運算規則,對

R、G、B、A

的數值分别進行縮放操作,當然在操作之前,會對現有的ColorMatrix進行初始化操作。

android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例
android - ColorMatrix詳解使用示例

矩陣表示:

android - ColorMatrix詳解使用示例

使用示例

這裡設定,所有的縮放比例為1.1

// 設定縮放比例

mColorMatrix.setScale(1.1f,1.1f,1.1f,1.1f);

// Log

D/TAG: [1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0]
           

從Log中我們可以看出,其結果也驗證了對于縮放的了解,圖檔效果如下 :

android - ColorMatrix詳解使用示例

縮放矩陣

我們還可以制作一個顔色通道,比如紅色 :

// 紅色通道

mColorMatrix.setScale(1,0,0,1);

// Log

D/TAG: [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]
           
android - ColorMatrix詳解使用示例

紅色通道

3、飽和度

API如下:

/**

* 設定矩陣顔色的飽和度

*

* sat 0表示灰階、1表示本身

*/

public void setSaturation(float sat)
           

灰階圖檔的去色原理:隻要把RGB的三色通道的數值設定為一樣,即

R=G=B

,那麼圖像就變成了灰色,同時為了保證圖像的亮度,需要使同一個通道中的

R+G+B

的結果接近1。setSaturation

方法可以根據一定比例,整體的增加或者減少顔色的飽和度,當設定0時,表示灰階圖檔;當設定為1時,表示顔色不變化。

  • 在matlab中按照 0.2989 R,0.5870 G 和 0.1140 B 的比例構成像素灰階值
  • 在OpenCV中按照 0.299 R, 0.587 G 和 0.114 B 的比例構成像素灰階值
  • 在Android中按照0.213 R,0.715 G 和 0.072 B 的比例構成像素灰階值

使用示例

這裡設定飽和度為0,測試下灰階效果

// 灰階

mColorMatrix.setSaturation(0f);

// Log

D/TAG: [0.213, 0.715, 0.072, 0.0, 0.0, 0.213, 0.715, 0.072, 0.0, 0.0, 0.213, 0.715, 0.072, 0.0, 0.0,

0.0, 0.0, 0.0, 1.0, 0.0]
           

列印出的Log也驗證了上述對于圖檔灰階的說明,當然源碼中還有對于飽和度從0%——100%的計算,感興趣的同學可以檢視以下源碼。灰階圖檔效果如下:

android - ColorMatrix詳解使用示例

飽和度矩陣

三、ColorMatrix相乘

1、設定

設定新的矩陣覆寫之前的内容,可以設定一個單獨的矩陣,也可以設定兩個矩陣的相乘。API如下:

public void set(ColorMatrix src)

public void set(float[] src)

public void setConcat(ColorMatrix matA, ColorMatrix matB)
           

這裡主要說一下

setConcat

方法,此方法表示兩個ColorMatrix相乘

android - ColorMatrix詳解使用示例

矩陣表示為:

使用示例

mColorMatrixA = new ColorMatrix(new float[]{

1,0.3f,0,0,0

,0,1,0.3f,0,0.1f

,0,0.6f,1,0,0

,0,0,0,1,1

});

mColorMatrixB = new ColorMatrix(new float[]{

1,0,0,0,1

,0,1,0,0,0.5f

,0.1f,0.9f,0.8f,0,0

,0,0,0,1,0.8f

});

mColorMatrix = new ColorMatrix(new float[]{

0,0,0,0,0

,0,0,0,0,0

,0,0,0,0,0

,0,0,0,0,0

});

mColorMatrix.setConcat(mColorMatrixA,mColorMatrixB);

Log.d("TAGA", Arrays.toString(mColorMatrixA.getArray()));

Log.d("TAGB", Arrays.toString(mColorMatrixB.getArray()));

Log.d("TAGAB", Arrays.toString(mColorMatrix.getArray()));

// Log

D/TAGA: [1.0, 0.3, 0.0, 0.0, 0.0, 0.0, 1.0, 0.3, 0.0, 0.1, 0.0, 0.6, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0]

D/TAGB: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.1, 0.9, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.8]

D/TAGAB: [1.0, 0.3, 0.0, 0.0, 1.15, 0.030000001, 1.27, 0.24000001, 0.0, 0.6, 0.1, 1.5, 0.8, 0.0, 0.3, 0.0, 0.0, 0.0, 1.0, 1.8]

           

2、前乘

前乘相當于,目前矩陣乘以輸入的矩陣

android - ColorMatrix詳解使用示例

這裡看一下源碼,可以更容易的了解:

1

2

3

4

// 邏輯上相當于調用setConcat(this, prematrix)

public void preConcat(ColorMatrix prematrix) {

setConcat(this, prematrix);

}

從源碼上可以明顯的看出前乘的規則,preConcat(prematrix)方法相當于調用setConcat(this, prematrix)方法

使用示例

1

2

3

mColorMatrix.reset();

mColorMatrix.preConcat(mColorMatrixA);

mColorMatrix.preConcat(mColorMatrixB);

上例多次調用preConcat,則相當于

android - ColorMatrix詳解使用示例

3、後乘

後乘相當于,輸入的矩陣乘以目前矩陣

android - ColorMatrix詳解使用示例

這裡看一下源碼,可以更容易的了解:

1

2

3

4

// 邏輯上相當于調用setConcat(postmatrix, this)

public void postConcat(ColorMatrix postmatrix) {

setConcat(postmatrix, this);

}

從源碼上可以明顯的看出前乘的規則,postConcat(prematrix)方法相當于調用setConcat(postmatrix, this)

使用示例

1

2

3

mColorMatrix.reset();

mColorMatrix.postConcat(mColorMatrixA);

mColorMatrix.postConcat(mColorMatrixB);

上例多次調用postConcat,因為矩陣滿足交換律,則相當于

android - ColorMatrix詳解使用示例

四、總結

本文我們學習了ColorMatrix的原理,并分析了其

setRotate、setScale、setSaturation

方法以及矩陣的乘法(前乘、後乘)。如果在閱讀過程中,有任何疑問與問題,歡迎與我聯系。

部落格:www.idtkm.com

GitHub:https://github.com/Idtk

微網誌:http://weibo.com/Idtk

郵箱:[email protected]

五、參考

ColorMatrix

Paint之ColorMatrix與濾鏡效果

Android Matrix矩陣詳解

轉載:http://www.idtkm.com/2016/09/18/13%E3%80%81ColorMatrix/