Paint之Xfermode的18種模式
請(qǐng)尊重原創(chuàng)诺核,轉(zhuǎn)載請(qǐng)注明出處【tianyl】的博客
關(guān)于的Android之玩轉(zhuǎn)View目錄
前言
說到Xfermode形耗,實(shí)現(xiàn)過圓形圖像的同學(xué)一定不會(huì)陌生,雖說之前的Shader篇中介紹了一種用Shader實(shí)現(xiàn)圓形圖像的方法酿愧,不過使用最廣泛的桶蝎,還是Xfermode
首先說明一下Xfermode是個(gè)什么東西,簡(jiǎn)單來講挽牢,它就是將一張圖片,根據(jù)另一張圖片摊求,來進(jìn)行一些處理禽拔,來達(dá)到想要的顯示效果,而它的處理方式,總共有18種睹栖,下面就來介紹一下這些處理方式
1 PorterDuff
PorterDuff.java是android.graphics
包下的一個(gè)類硫惕,它有一個(gè)枚舉的子類Mode,這個(gè)Mode類就定義了這18種處理方式
因?yàn)槠蜻@里就不放代碼了野来,直接貼圖片
上圖就是這18種處理模式恼除,下圖是它們的處理結(jié)果(還有兩種新增的模式的圖在后面)
下面來分別介紹它們的處理規(guī)則
1.1 顏色計(jì)算說明
首先說明,對(duì)于這18種模式曼氛,Android都是通過兩張圖片的顏色值進(jìn)行特殊的計(jì)算豁辉,而得到一張新的圖片進(jìn)行實(shí)現(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]
很顯然餐抢,這個(gè)模式下的圖標(biāo)就是什么都沒有,如上圖16種模式中的Clear
1.3 PorterDuff.Mode.SRC
原圖模式
Android源碼中的顏色數(shù)組為[Sa,Sc]
這個(gè)模式下的繪制出來的就是原圖
1.4 PorterDuff.Mode.Dst
目標(biāo)圖模式
Android源碼中的顏色數(shù)組為[Da, Dc]
這個(gè)模式下的繪制出來的就是目標(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],所以這個(gè)模式只會(huì)繪制兩者相交的區(qū)域团滥,并且相交區(qū)域受目標(biāo)圖的alpha值影響
1.8 PorterDuff.Mode.DST_IN
繪制目標(biāo)圖竿屹,受原圖alpha值影響
Android源碼中的顏色數(shù)組為[Sa * Da, Sa * Dc]
因?yàn)楹蚐RC_IN相反,所以這里也不解釋了
1.9 PorterDuff.Mode.SRC_OUT
繪制原圖灸姊,去掉相交部分
Android源碼中的顏色數(shù)組為[Sa * (1 - Da), Sc * (1 - Da)]
很顯然拱燃,如果Da(目標(biāo)圖的alpha值)為1,那么數(shù)組值為[0,0]力惯,所以只會(huì)繪制目標(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時(shí)(完全不透明)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的時(shí)候,這個(gè)值為0豹芯,也就是兩者完全不透明并且相交的時(shí)候不繪制悄雅,除此之外都會(huì)繪制
color值受兩者的color值影響,計(jì)算公式是:Sc * (1 - Da) + (1 - Sa) * Dc
1.14 PorterDuff.Mode.DARKEN
字面翻譯就是變暗模式,兩者都繪制铁蹈,并且在兩者相交的位置對(duì)顏色進(jìn)行處理(也就是所謂的變暗)
Android源碼中的顏色數(shù)組為[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]
alpha值為Sa + Da - Sa*Da千元,因?yàn)閍lpha的值在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計(jì)算和DARKEN一樣蜗字,更加不透明,顏色計(jì)算這里取的是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的時(shí)候措嵌,全透明躲叼,只有當(dāng)兩者都不透明時(shí),繪制圖像企巢,color值為Sc * Dc
1.17 PorterDuff.Mode.SCREEN
字面翻譯就是屏幕(說好聽一點(diǎn)叫濾色)枫慷,繪制所有區(qū)域,并處理
Android源碼中的顏色數(shù)組為[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
1.18 PorterDuff.Mode.ADD
疊加飽和度浪规,這個(gè)算是后面加的一種模式
官方文檔上的alpha值和color值計(jì)算規(guī)則
效果圖如下
1.19 PorterDuff.OVERLAY
疊加模式
官方文檔上的alpha值和color值計(jì)算規(guī)則
效果圖如下
由于后兩者ADD模式和OVERLAY是后面加的或听,所有這里就直接使用Google官方的效果圖展示了
1.20 總結(jié)
到此,關(guān)于Xfermode的18種模式就介紹完了罗丰,當(dāng)然神帅,關(guān)于這些模式中的顏色計(jì)算和圖片計(jì)算,本文都只是說明了一個(gè)大概萌抵,具體的含義并沒有深究(畢竟我只是一個(gè)程序員找御,不懂美術(shù)霸啤),如果有同學(xué)對(duì)這方面有興趣霎桅,可以看一下這篇科普栖疑,關(guān)于部分顏色處理公式的物理含義都有解釋
最后,由于這部分內(nèi)容是科普向的內(nèi)容滔驶,就不放demo展示了遇革,后續(xù)做一些特效實(shí)現(xiàn)吧(ˇ?ˇ)