Android靈魂畫家的18種混合模式

image

??? Warning!Warning!前方高能,閱讀本文可能需要3分鐘哦!

有什么料?

  1. 重新認(rèn)識(shí)神秘的PorterDuffXfermode。
  2. 學(xué)會(huì)正確的使用PorterDuffXfermode。
  3. 收獲【兩張示例圖】,幫助你在實(shí)際中正確的運(yùn)用各種混合模式。

解密PorterDuffXfermode

先上兩張示例圖,大家快來保存??!

image
image

注:這兩張圖僅用了兩個(gè)強(qiáng)大的View完成的。【從未如此驚艷!你好,SuperTextView (v1.1) - http://www.itdecent.cn/p/1b91e11e441d】,你值得擁有!

自己繪過圖的筒靴一定見過或者用過mPaint.setXfermode(Xfermode xfermode),它是干什么的呢?它的作用就是將畫布上的當(dāng)前圖像(即目標(biāo)圖像DST)和后面需要繪制的圖像(即源圖像SRC)按照一定的算法進(jìn)行混合。簡單點(diǎn)說就是把源圖像SRC目標(biāo)圖像DST進(jìn)行混合。而ProterDuffXfermode繼承自Xfermode,提供了18像素混合模式的算法,它們是由Thomas PorterTom Duff在 于1984年7月的一篇名為【《Compositing Digital Images》https://keithp.com/~keithp/porterduff/p253-porter.pdf】的論文中提出的。這對(duì)圖像處理來說具有重大的意義。

Xfermode的意義你知道嗎?

在上面的兩張圖中,CoorChice已經(jīng)向筒靴們展示了使用Xfermode來混合簡單的圖形所達(dá)到的效果。

對(duì)于一些比較難畫的圖形,如果通過運(yùn)算坐標(biāo)和尺寸去繪制當(dāng)然是可以的。但是這些運(yùn)算將會(huì)非常復(fù)雜!如果合理的使用Xfermode去將一些簡單的圖形進(jìn)行混合,同樣可以獲得你所期望的復(fù)雜圖形。在CoorChice的這篇文章【從未如此驚艷!你好,SuperTextView (v1.1)http://www.itdecent.cn/p/1b91e11e441d】 中,CoorChice向你展示了一個(gè)掃光特效,它的兩端有個(gè)截?cái)嘈Ч?,就是通過Xfermode完成的。如果靠計(jì)算的話,實(shí)現(xiàn)起來會(huì)稍微費(fèi)點(diǎn)力。

當(dāng)然,這些并不能發(fā)揮Xfermode的真正威力。如果你使用它對(duì)一些圖片進(jìn)行混合,你會(huì)看到Xfermode到底能做什么不可思議的事!比如,在 《Compositing Design Images》 中就有一個(gè)這樣的例子:

image

圖中最后Composite的結(jié)果就是前面幾張圖片通過一定組合合成的,這是合成算法:

(FFire plus (BFire out Plant)) over Darken(Plant, .8) over Stars .

你看,Xfermode就是如此的強(qiáng)大,通過合理的組合,能合成圖片。

再一看張CoorChice用圖片合成的各種效果:

image

哇!這魚飛起來啦!

18種混合模式

《Compositing Degital Images》 中,Thomas PorterTom Duff展示了12中基本的混合模式:

image

我們可以將上圖中的A對(duì)應(yīng)目標(biāo)圖像DST,B對(duì)應(yīng)源圖像SRC去理解。通過組合這12種混合模式,足夠?qū)崿F(xiàn)任意的2D圖像合成效果了。十分的強(qiáng)大。對(duì)照著上面CoorChice畫的圖理解吧。

也許筒靴們平時(shí)都只聽說PorterDuff.Mode是16種模式,因?yàn)楣俜降睦又芯统霈F(xiàn)了16種模式。但事實(shí)上,Android提供的混合模式共有18種,筒靴們?cè)谏蠄D中也是能看到滴。就是最后一排的ADDOVERLAY是不常被提到的。

下面CoorChice和大家一起捋一捋這18種混合模式:
在此之前,先說明下各個(gè)符號(hào)的意義。
在支持透明通道的情況下,一個(gè)像素點(diǎn)通過alpha透明值和RGB色值來描述,即[alpha, rgb]



Sa: Src Alpha,即源圖像的透明值

Sc:Src color,即源圖像的色值

Da:Dst Alpha,即目標(biāo)圖像的透明值

Dc:Dst color,即目標(biāo)圖像的色值

PorterDuff.Mode 算法 作用
CLEAR [0, 0] 圖像的alpha和rgb值均為0.
SRC [Sa, Sc] 取源圖像的值。
DST [Da, Dc] 取目標(biāo)圖像的值。
SRC_OVER [Sa + (1 - Sa)Da, Rc = Sc + (1 - Sa)Dc] 結(jié)果是Src蓋在了Dst上。注意alpha值的影響,不一定是這個(gè)結(jié)果。
DST_OVER [Sa + (1 - Sa)Da, Rc = Dc + (1 - Da)Sc] 結(jié)果是Dst蓋在了Src上。注意alpha值的影響,不一定是這個(gè)結(jié)果。
SRC_IN [Sa * Da, Sc * Da] 結(jié)果是在Src色值不為0的地方,且Dst透明值不為0的地方能看到合成圖像。
DST_IN [Sa * Da, Sa * Dc] 結(jié)果是在Dst色值不為0的地方,且Src透明值不為0的地方能看到合成圖像。
SRC_OUT [Sa * (1 - Da), Sc * (1 - Da)] 結(jié)果是在Src色值不為0,且Dst透明值不為1的地方能看到合成圖像。
DST_OUT [Da * (1 - Sa), Dc * (1 - Sa)] 結(jié)果是在Dst色值不為0,且Src透明值不為1的地方能看到合成圖像。
SRC_ATOP [Da, Sc * Da + (1 - Sa) * Dc] 結(jié)果是在Src和Dst色值不同時(shí)為0,且Dst透明值不為0,且當(dāng)Src色值為0但Src透明值不為1的地方能看到合成圖像。
DST_ATOP [Sa, Sa * Dc + Sc * (1 - Da)] 結(jié)果是在Src和Dst色值不同時(shí)為0,且Src透明值不為0,且當(dāng)Dst色值為0但Dst透明值不為1的地方能看到合成圖像。
XOR [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 在不相交的地方按原樣繪制源圖像和目標(biāo)圖像,相交的地方受到對(duì)應(yīng)alpha和色值影響。
DARKEN [Sa + Da - SaDa, Sc(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] 取較暗的透明值,色值計(jì)算相對(duì)復(fù)雜。
LIGHTEN [Sa + Da - SaDa, Sc(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] 取較亮的透明值,色值計(jì)算相對(duì)復(fù)雜。
MUTIPLY [Sa * Da, Sc * Dc] 結(jié)果是在Src和Dst透明值均不為0,且色值均不為0的地方能看到合成圖像。
SCREEN [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] 可以看到,它可能有多種情況,需要實(shí)際計(jì)算。
ADD Saturate(S + D)
OVERLAY

筒靴們對(duì)著上面【Bitmap繪制】圖來看這18種混合模式。

令人困惑的圖

筒靴們可以看到【Bitmap繪制】圖和官方的例子圖是一樣一樣的,但是很多筒靴自己畫出來的效果卻和【Canvas直接繪制】圖是一樣一樣的。嗯,百思不解!有沒有可能是官方的例子錯(cuò)了呢?

想多了,沒有的。只是筒靴們沒注意到官方標(biāo)準(zhǔn)例子中的細(xì)節(jié):

  • 首先需要關(guān)閉硬件加速。因?yàn)橛布铀倌J较?,渲染是通過GPU完成的,和普通CPU渲染可能有點(diǎn)不一樣,導(dǎo)致了部分合成算法呈現(xiàn)的效果有差異。你可以看看我的這篇文章【用兩張圖告訴你,為什么你的App會(huì)卡頓?http://www.itdecent.cn/p/df4d5ec779c8】,了解下View的繪制流程。
  • 其次,像素混合是對(duì)兩個(gè)區(qū)域進(jìn)行的。官方的示例中,黃圓和藍(lán)正方形都是畫在大小和黑色邊框相等的Bitmap上的,然后再將兩個(gè)Bitmap的像素進(jìn)行混合,此時(shí)兩個(gè)Bitmap的區(qū)域是【完全重合】的。所以得到了標(biāo)準(zhǔn)效果。而很多同學(xué)可能沒注意,往往就以為兩個(gè)區(qū)域大小就是兩個(gè)圖形的外接矩形的大小,而它們相交的地方只有1/4。所以得到了“Canvas直接繪制”圖的效果。兩種方式最大的差別在于,【Bitmap繪制】圖中有一部分透明像素點(diǎn)參與了混合,而【Canvas直接繪制】圖中幾乎沒有。

這是CoorChice寫的示例,就是上面幾幅圖的實(shí)現(xiàn),【Github:https://github.com/chenBingX/CoorChiceLibOne/blob/448cf36e0b33fb667cb4fd5a8d8db2651bf0647e/app/src/main/java/com/chenbing/coorchicelibone/Views/PorterDuffXDemoActivity.java】,大家可以對(duì)照的動(dòng)手感受一下。

總結(jié)

  • 抽出空余時(shí)間寫文章分享需要?jiǎng)恿?,還請(qǐng)各位看官動(dòng)動(dòng)小手點(diǎn)個(gè)贊,給我點(diǎn)鼓勵(lì)
  • 我一直在不定期的創(chuàng)作新的干貨,想要上車只需進(jìn)到我的【個(gè)人主頁】點(diǎn)個(gè)關(guān)注就好了哦。發(fā)車嘍~

本篇文章向大家詳細(xì)的展示了強(qiáng)大的PorterDuffXfermode的正確打開方式,CoorChice相信以后不會(huì)再有筒靴抱怨:我的天吶!這玩意兒有毒!為什么我合成出來的圖像和官方示例不一樣!

參考鏈接

  1. Api PorterDuff.Mode - https://developer.android.com/reference/android/graphics/PorterDuff.Mode.html
  2. Xfermode in android - http://weishu.me/2015/09/23/Xfermode-in-android/
  3. Compositing Digital Images - https://keithp.com/~keithp/porterduff/p253-porter.pdf

看到這里的童鞋快獎(jiǎng)勵(lì)自己一口辣條吧!

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

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.aiuxian.com/article/p-1982467.html 接下來...
    lucky_yaya閱讀 7,037評(píng)論 3 9
  • Paint 類持有繪制圖形、文本、圖像的樣式和色彩信息,并且對(duì)外提供了一系列方法來設(shè)置這些信息。 一、畫筆基本操作...
    秀花123閱讀 4,607評(píng)論 1 7
  • 在Paint中有很多的屬性可以設(shè)置,比如可以設(shè)置陰影,顏色過濾等等,這些會(huì)產(chǎn)生不同的奇妙效果,今天就對(duì)各種屬性探索...
    Jwennnnnnnnnn閱讀 2,644評(píng)論 0 2
  • 是該說再見了,我們都不是誰的誰,生活中也只有血緣關(guān)系最為長久。抹不掉,除不了,也是血緣關(guān)系最為牢靠與忠誠。它不需...
    自律的自由s閱讀 430評(píng)論 0 0
  • 三 庭院里,鶯飛燕舞,花草叢生。 空氣里隱隱透著一絲壓抑的燥熱,虛了眼看去竟有凡間盛夏才有的波動(dòng)。 這當(dāng)鋪處處皆可...
    鄙人十九閱讀 524評(píng)論 0 0

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