Android之玩轉(zhuǎn)View(四):Paint之Xfermode的18種模式

Paint之Xfermode的18種模式

請尊重原創(chuàng),轉(zhuǎn)載請注明出處【tianyl】的博客

關(guān)于的Android之玩轉(zhuǎn)View目錄

前言

說到Xfermode,實現(xiàn)過圓形圖像的同學(xué)一定不會陌生,雖說之前的Shader篇中介紹了一種用Shader實現(xiàn)圓形圖像的方法,不過使用最廣泛的,還是Xfermode

首先說明一下Xfermode是個什么東西,簡單來講,它就是將一張圖片,根據(jù)另一張圖片,來進(jìn)行一些處理,來達(dá)到想要的顯示效果,而它的處理方式,總共有18種,下面就來介紹一下這些處理方式

1 PorterDuff

PorterDuff.java是android.graphics包下的一個類,它有一個枚舉的子類Mode,這個Mode類就定義了這18種處理方式

因為篇幅原因這里就不放代碼了,直接貼圖片


上圖就是這18種處理模式,下圖是它們的處理結(jié)果(還有兩種新增的模式的圖在后面)


下面來分別介紹它們的處理規(guī)則

1.1 顏色計算說明

首先說明,對于這18種模式,Android都是通過兩張圖片的顏色值進(jìn)行特殊的計算,而得到一張新的圖片進(jìn)行實現(xiàn)的,用數(shù)組[x,y]表示(Sa表示原圖的alpha值,Da表示目標(biāo)圖的alpha值,Sc表示原圖的color值,Dc表示目標(biāo)圖的color值

其中x表示結(jié)果圖片的alpha值,y表示結(jié)果圖片的color值

1.2 PorterDuff.Mode.CLEAR

清除模式
Android源碼中的顏色數(shù)組為[0,0]
很顯然,這個模式下的圖標(biāo)就是什么都沒有,如上圖16種模式中的Clear

1.3 PorterDuff.Mode.SRC

原圖模式
Android源碼中的顏色數(shù)組為[Sa,Sc]
這個模式下的繪制出來的就是原圖

1.4 PorterDuff.Mode.Dst

目標(biāo)圖模式
Android源碼中的顏色數(shù)組為[Da, Dc]
這個模式下的繪制出來的就是目標(biāo)圖

1.5 PorterDuff.Mode.SRC_OVER

原圖覆蓋
Android源碼中的顏色數(shù)組為[Sa + (1 - Sa)*Da, Sc + (1 - Sa)*Dc]
很顯然,如果Sa透明度為1(即完全不透明,那么繪制的是原圖,否則繪制的是目標(biāo)圖,如果是半透明那么兩者都有)

顯示出來的效果就是原圖將目標(biāo)圖覆蓋了

1.6 PorterDuff.Mode.DST_OVER

目標(biāo)圖覆蓋
Android源碼中的顏色數(shù)組為[Sa + (1 - Sa)*Da, Dc + (1 - Da)*Sc]
和SRC_OVER正好相反,就不解釋了

顯示出來的效果就是目標(biāo)圖將原圖覆蓋了

1.7 PorterDuff.Mode.SRC_IN

繪制原圖,但是受目標(biāo)圖的alpha值影響
Android源碼中的顏色數(shù)組為[Sa * Da, Sc * Da]
如果Da(目標(biāo)圖的alpha值)為0,那么數(shù)組的值就是[0,0],所以這個模式只會繪制兩者相交的區(qū)域,并且相交區(qū)域受目標(biāo)圖的alpha值影響

1.8 PorterDuff.Mode.DST_IN

繪制目標(biāo)圖,受原圖alpha值影響
Android源碼中的顏色數(shù)組為[Sa * Da, Sa * Dc]
因為和SRC_IN相反,所以這里也不解釋了

1.9 PorterDuff.Mode.SRC_OUT

繪制原圖,去掉相交部分
Android源碼中的顏色數(shù)組為[Sa * (1 - Da), Sc * (1 - Da)]
很顯然,如果Da(目標(biāo)圖的alpha值)為1,那么數(shù)組值為[0,0],所以只會繪制目標(biāo)圖alpha值不為1的部分,并且最后顏色的也和目標(biāo)圖的alpha的值有關(guān)

1.10 PorterDuff.Mode.DST_OUT

繪制目標(biāo)圖,去掉相交部分
Android源碼中的顏色數(shù)組為[Da * (1 - Sa), Dc * (1 - Sa)]
和SRC_OUT相反,解釋略

1.11 PorterDuff.Mode.SRC_ATOP

主要繪制目標(biāo)圖,如果存在相交部分,則繪制原圖
Android源碼中的顏色數(shù)組為[Da, Sc * Da + (1 - Sa) * Dc]

顯然,alpha的值為Da,所以只繪制目標(biāo)圖,而當(dāng)Sa為1時(完全不透明)color值為Sc * Da,所以相交部分繪制原圖,但是受Da值的影像

1.12 PorterDuff.Mode.DST_ATOP

主要繪制原圖,如果存在相交部分,則繪制目標(biāo)圖
Android源碼中的顏色數(shù)組為[Sa, Sa * Dc + Sc * (1 - Da)]

和SRC_ATOP相反,解釋略

1.13 PorterDuff.Mode.XOR

異或模式,相交部分不繪制,繪制不相交部分
Android源碼中的顏色數(shù)組為[Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]

顯然,alpha的值為Sa + Da - 2 * Sa * Da,只有Sa=Da=1的時候,這個值為0,也就是兩者完全不透明并且相交的時候不繪制,除此之外都會繪制
color值受兩者的color值影響,計算公式是:Sc * (1 - Da) + (1 - Sa) * Dc

1.14 PorterDuff.Mode.DARKEN

字面翻譯就是變暗模式,兩者都繪制,并且在兩者相交的位置對顏色進(jìn)行處理(也就是所謂的變暗)
Android源碼中的顏色數(shù)組為[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]

alpha值為Sa + Da - Sa*Da,因為alpha的值在0到1之間,所以alpha值是增大的,所以更加不透明了
color值為Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)

1.15 PorterDuff.Mode.LIGHTEN

和DARKEN相反,字面意思就是變亮
Android源碼中的顏色數(shù)組為[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
alpha計算和DARKEN一樣,更加不透明,顏色計算這里取的是max(Sc, Dc),而DARKEN里取的是min(Sc, Dc),我們知道顏色越小就越暗(黑色是000000,白色是ffffff)

1.16 PorterDuff.Mode.MULTIPLY

字面翻譯就是正片疊底,只繪制相交區(qū)域,并處理
Android源碼中的顏色數(shù)組為[Sa * Da, Sc * Dc]

顯然,當(dāng)Sa為0或者Da為0的時候,全透明,只有當(dāng)兩者都不透明時,繪制圖像,color值為Sc * Dc

1.17 PorterDuff.Mode.SCREEN

字面翻譯就是屏幕(說好聽一點叫濾色),繪制所有區(qū)域,并處理
Android源碼中的顏色數(shù)組為[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]

1.18 PorterDuff.Mode.ADD

疊加飽和度,這個算是后面加的一種模式
官方文檔上的alpha值和color值計算規(guī)則


效果圖如下


1.19 PorterDuff.OVERLAY

疊加模式
官方文檔上的alpha值和color值計算規(guī)則


效果圖如下


由于后兩者ADD模式和OVERLAY是后面加的,所有這里就直接使用Google官方的效果圖展示了

1.20 總結(jié)

到此,關(guān)于Xfermode的18種模式就介紹完了,當(dāng)然,關(guān)于這些模式中的顏色計算和圖片計算,本文都只是說明了一個大概,具體的含義并沒有深究(畢竟我只是一個程序員,不懂美術(shù)啊),如果有同學(xué)對這方面有興趣,可以看一下這篇科普,關(guān)于部分顏色處理公式的物理含義都有解釋

最后,由于這部分內(nèi)容是科普向的內(nèi)容,就不放demo展示了,后續(xù)做一些特效實現(xiàn)吧(ˇ?ˇ)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容