動腦學(xué)院UI預(yù)習(xí)資料-Paint(濾鏡,顏色通道,矩陣運算)

前言

在之前的幾次課當(dāng)中我們已經(jīng)詳細了解到整個android程序,從啟動再到繪制的整體流程,從這中間我們又牽扯出了Canvas繪制圖形的畫板和我們的Paint控制色彩樣式的畫筆,那么之前基礎(chǔ)篇我們就不進行詳細的解釋,那些API在之前的基礎(chǔ)篇已經(jīng)公布出來,我也注釋的非常詳細,今天我門來了解Paint高級篇真正需要了解的濾鏡

濾鏡

1.濾鏡效果

12625345-83728b2a6858c8e6.png

從上圖我們可以看到 四張濾鏡效果圖像,其色彩的顯示效果各不一樣,也就是說所謂濾鏡其實只不過是對于原本圖像色彩進行調(diào)整
那么需要對圖像的色彩進行調(diào)整操作,我們會需要知道幾個概念,那就是我們的圖像構(gòu)成,顏色通道,顏色模式以及顏色舉證

2.圖像構(gòu)成

在具體講濾鏡之前,今天我們先來系統(tǒng)化真正認識一下在我們計算機當(dāng)中我們的圖像到底是什么,我們都知道在計算機體系當(dāng)中我們的圖像有各種各樣的格式,比如jpg,png,gif等等...
那么我們同樣也知道我們計算機當(dāng)中的圖像文件其實實際也就是一個二進制的字節(jié)碼文件,那么這個圖像本質(zhì)上來說是一個二進制文件,然后我們的cpg,gpu對二進制文件進行識別再顯示到我們的屏幕上,那么我們現(xiàn)在需要關(guān)注的是,這些文件當(dāng)中他到底保存的是什么?
其實一個圖像文件當(dāng)中,他保存的數(shù)據(jù)總體分為兩塊
1.圖像的信息
2.圖像的數(shù)據(jù)
后者好理解,我們可以理解為圖像具體的那些像素點的數(shù)據(jù),
那么前者其實我們可以理解為,是一組信息,這組信息的作用是讓我們的cpg,gpu在顯示圖像的時候,基于我門設(shè)定的這組信息的規(guī)則不同,那么顯示的效果不一樣,
以一種格式(PNG)為例,我在網(wǎng)上扒出了對于這個圖像的結(jié)構(gòu)的解釋(粗略看一下就好)
PNG的文件結(jié)構(gòu)

對于一個PNG文件來說,其文件頭總是由位固定的字節(jié)來描述的:

十進制數(shù)    137 80 78 71 13 10 26 10
十六進制數(shù)   89 50 4E 47 0D 0A 1A 0A
其中第一個字節(jié)0x89超出了ASCII字符的范圍,這是為了避免某些軟件將                PNG文件當(dāng)做文本文件來處理。文件中剩余的部分由3個以上的PNG的數(shù)據(jù)塊(Chunk)按照特定的順序組成,因此,一個標(biāo)準(zhǔn)的PNG文件結(jié)構(gòu)應(yīng)該如下:

PNG文件標(biāo)志 PNG數(shù)據(jù)塊  ……  PNG數(shù)據(jù)塊
PNG數(shù)據(jù)塊(Chunk)

PNG定義了兩種類型的數(shù)據(jù)塊,一種是稱為關(guān)鍵數(shù)據(jù)塊(critical chunk),這是標(biāo)準(zhǔn)的數(shù)據(jù)塊,另一種叫做輔助數(shù)據(jù)塊(ancillary chunks),這是可選的數(shù)據(jù)塊。關(guān)鍵數(shù)據(jù)塊定義了4個標(biāo)準(zhǔn)數(shù)據(jù)塊,每個PNG文件都必須包含它們,PNG讀寫軟件也都必須要支持這些數(shù)據(jù)塊。雖然PNG文件規(guī)范沒有要求PNG編譯碼器對可選數(shù)據(jù)塊進行編碼和譯碼,但規(guī)范提倡支持可選數(shù)據(jù)塊。

下表就是PNG中數(shù)據(jù)塊的類別,其中,關(guān)鍵數(shù)據(jù)塊部分我們使用深色背景加以區(qū)分。


為了簡單起見,我們假設(shè)在我們使用的PNG文件中,這4個數(shù)據(jù)塊按以上先后順序進行存儲,并且都只出現(xiàn)一次。

數(shù)據(jù)塊結(jié)構(gòu)

PNG文件中,每個數(shù)據(jù)塊由4個部分組成,如下:

名稱  字節(jié)數(shù) 說明
Length (長度) 4字節(jié) 指定數(shù)據(jù)塊中數(shù)據(jù)域的長度,其長度不超過(231-1)字節(jié)
Chunk Type Code (數(shù)據(jù)塊類型碼)    4字節(jié) 數(shù)據(jù)塊類型碼由ASCII字母(A-Z和a-z)組成
Chunk Data (數(shù)據(jù)塊數(shù)據(jù))  可變長度    存儲按照Chunk Type Code指定的數(shù)據(jù)
CRC (循環(huán)冗余檢測)    4字節(jié) 存儲用來檢測是否有錯誤的循環(huán)冗余碼

從上面這一段解釋當(dāng)中我門可以看出,其實所謂的各個圖像格式只不過是發(fā)布的標(biāo)準(zhǔn)不一樣,那么們cpu解析的規(guī)則也不一致,同時一張圖片里面包含了多個數(shù)據(jù)塊,如下圖


12625345-029742925665b437.png

這是我打開的一張jpg圖的數(shù)據(jù),這時我門看到的是16進制的數(shù)據(jù),盡管我們不知道這些數(shù)據(jù)是什么,那么此時我們結(jié)合上述所說,假定第一行的數(shù)據(jù)是這個jpg的標(biāo)志,第2-8行可能記錄的是解析規(guī)則等等信息類似,后面的為數(shù)據(jù),那么這樣去看待一張圖形,我們就能大致明白一個意思, 標(biāo)志+圖像信息+數(shù)據(jù)--》最終構(gòu)成一張完整的圖像,圖像根據(jù)數(shù)據(jù)和所為的解析規(guī)則計算顯示出來的
那么對于今天的濾鏡,我門需要了解到圖像當(dāng)中比較重要的兩個信息顏色通道,顏色模式

3.顏色通道,顏色模式

顏色通道:保存圖像顏色信息的通道稱為顏色通道。這句話是顏色通道的基本定義,我門可以理解為記錄色彩信息的那一段數(shù)據(jù),
每個圖像都有一個或者多個顏色通道,圖像中默認的顏色通道信息取決于顏色模式

顏色模式:顏色模式我門可以理解為將某種顏色表現(xiàn)為數(shù)字形式的模型,或者說是一種記錄圖像顏色的方式。分為:RGB模式、CMYK模式、HSB模式、Lab顏色模式、位圖模式、灰度模式、索引顏色模式、雙色調(diào)模式和多通道模式等。
其實實際上我們就認為,現(xiàn)在我要顯示的色彩這個時候是用數(shù)字表示,最經(jīng)典的RGB模式我們可以理解為R(255) G(0) B(0)當(dāng)前這個像素,顯示,在識別的時候為紅色,他由紅 綠 藍 三種色彩進行混合,顯示出我們要的顏色其程度數(shù)值是0-255的范圍

總結(jié):也就是說,其實圖像的顯示,每個點都是由模式所決定的色彩數(shù)值混合形成我們想要的顏色,那么我們的濾鏡效果實現(xiàn),其實實際上就是去對于顏色通道進行過濾操作,在其原本的模式數(shù)值上面進行操作,達到更改圖像色彩效果的目的,這就是我們所為的濾鏡

4.顏色矩陣

在android當(dāng)中,他所采用的顏色模式是RGBA模式,也就是在紅綠藍的基礎(chǔ)上加入了Alpha透明度的概念,那么也就是他現(xiàn)在是一個四通道的模式
在Android當(dāng)中當(dāng)android將圖像信息獲取出來時候,當(dāng)前圖像的顏色通道信息他用的是一個矩陣在進行保存

用一個數(shù)組來表示的話就是


12625345-120def1adf2a5fab.png
12625345-aa867504e3102a19.png

上面這里看到的是一個四通道形式的表示方式,我門會發(fā)現(xiàn)在
1-1
2-2
3-3
4-4
的位置都是一個1的數(shù)值,那么幾個數(shù)值我們把他理解為顏色的系數(shù),1為原本數(shù)值不動,若0.5那么當(dāng)前對應(yīng)的rgba四個選項按比例處理
如果想要更改為半透明的,那么,當(dāng)前a的值改為0.5就OK了紅色翻一倍就改為2

但是如果在這種情況下


12625345-3b598f28ea3e5b1f.png

這個四介矩陣做不到,在android當(dāng)中真正的表現(xiàn)方式他應(yīng)用了一個4*5的矩陣


12625345-b6fdc9af0933863b.png

最后方加入一列,作為所為的亞元坐標(biāo),其實也就是分量值
那么下面這個顏色的矩陣如果想要將我們的顏色值達到上訴效果,第二行的100表示在之前的顏色基礎(chǔ)上增加100個綠色數(shù)值

那么這種是我們最為簡單的理解,
而真正的他當(dāng)中的實現(xiàn)實際上是采用矩陣的計算

4.矩陣運算


12625345-919bf822b43cf5aa.png

12625345-68007f0b7fb07fa8.png

矩陣的運算規(guī)則是矩陣A的一行乘以矩陣C的一列作為矩陣R的一行,
C矩陣是圖片中包含的ARGB信息,R矩陣是用顏色矩陣應(yīng)用于C之后的新的顏色分量,運算結(jié)果如下:

R' = aR + bG + cB + dA + e;
G' = fR + gG + hB + iA + j;
B' = kR + lG + mB + nA + o;
A' = pR + qG + rB + sA + t;

顏色矩陣并不是看上去那么深奧,其實需要使用的參數(shù)很少,而且很有規(guī)律第一行決定紅色第二行決定綠色
第三行決定藍色,第四行決定了透明度,第五列是顏色的偏移量。下面是一個實際中使用的顏色矩陣。


12625345-32588de209734d52.png

如果把這個矩陣作用于各顏色分量的話,R=A*C,計算后會發(fā)現(xiàn),各個顏色分量實際上沒有任何的改變(R'=R G'=G B'=B A'=A)。


image.png

圖1.5所示矩陣計算后會發(fā)現(xiàn)紅色分量增加100,綠色分量增加100,
這樣的效果就是圖片偏黃,因為紅色和綠色混合后得到黃色,黃色增加了100,圖片當(dāng)然就偏黃了。


image.png

改變各顏色分量不僅可以通過修改第5列的顏色偏移量也可如上面矩陣所示將對應(yīng)的顏色值乘以一個倍數(shù),直接放大。
上圖1.6是將綠色分量乘以2變?yōu)樵瓉淼?倍。至此已經(jīng)明白了如何通過顏色矩陣來改變各顏色分量。

5.濾鏡實現(xiàn)

那么在對于的實現(xiàn)上面android的使用非常簡單,只需要依賴于一個API就好
// 顏色通道過濾
/*ColorMatrix colorMartrix = new ColorMatrix(new float[]{
1, 0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,1,0,
});
paint.setColorFilter(new ColorMatrixColorFilter(colorMartrix));

那么下面是我的demo代碼,大家可以去試試效果
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setLayerType(View.LAYER_TYPE_SOFTWARE,null);

RectF rectF = new RectF(0,100,bitmap.getWidth(),bitmap.getHeight());
paint.reset();
paint.setColor(Color.RED);

canvas.drawBitmap(bitmap,null, rectF,paint);
// 平移運算---加法
/*ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1, 0,0,0,0,
        0,1,0,0,100,
        0,0,1,0,0,
        0,0,0,1,0,
});*/

// 反相效果 -- 底片效果

/* ColorMatrix colorMartrix = new ColorMatrix(new float[]{
-1, 0,0,0,255,
0,-1,0,0,255,
0,0,-1,0,255,
0,0,0,1,0,
});/
// 縮放運算---乘法 -- 顏色增強
/
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
1.2f, 0,0,0,0,
0,1.2f,0,0,0,
0,0,1.2f,0,0,
0,0,0,1.2f,0,
});*/

// 黑白照片
// 去色原理:只要把R G B 三通道的色彩信息設(shè)置成一樣,那么圖像就會變成灰色,
// 同時為了保證圖像亮度不變,同一個通道里的R+G+B =1
//
/*ColorMatrix colorMartrix = 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,
});*/

// 發(fā)色效果---(比如紅色和綠色交換)
/*ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        0,1,0,0,0,
        1, 0,0,0,0,
        0,0,1,0,0,
        0,0,0,1,0,
});*/
// 復(fù)古效果
/*ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1/2f,1/2f,1/2f,0,0,
        1/3f, 1/3f,1/3f,0,0,
        1/4f,1/4f,1/4f,0,0,
        0,0,0,1,0,
});*/
// 顏色通道過濾

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

RectF rectF2 = new RectF(600,100,600 + bitmap.getWidth(),bitmap.getHeight());
paint.setColorFilter(new ColorMatrixColorFilter(colorMartrix));


canvas.drawBitmap(bitmap,null, rectF2,paint);

}

那么關(guān)于濾鏡其他的反轉(zhuǎn),光影等效果課上講,大家可以試試這里最基礎(chǔ)的一些操作

作者:KerwinBarry
鏈接:http://www.lxweimin.com/p/4cbeffbf2f19
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。