五、Android繪制知識總結(jié)(Xfermode和硬件加速)

一徽缚、Xfermode

Xfermode表示圖層的混合模式憨奸,用于描述兩個圖層之間進(jìn)行融合時,像素點(diǎn)進(jìn)行計算的規(guī)則猎拨。

在API16之前膀藐,Xfermode有3個子類:AvoidXfermode屠阻、PixelXorXfermode、PorterDuffXfermode额各。但在API16以后国觉,前兩個已經(jīng)過時,甚至從源碼里移除虾啦,所以我們只需學(xué)習(xí)PorterDuffXfermode即可麻诀。

1.1、PorterDuffXfermode

PorterDuffXfermode最早是在1984年由Porter和Duff兩人發(fā)表的論文《Compositing Digital Images》中出現(xiàn)傲醉,所以該混合模式也根據(jù)作者來命名蝇闭。

PorterDuffXfermode構(gòu)造函數(shù)需要指定一個PorterDuff.Mode,而PorterDuff.Mode在以下地方都會涉及:

  • 1硬毕、ComposeShader
  • 2呻引、Paint.setXfermode()
  • 3、PorterDuffColorFilter

它提供18種模式可選項:

PorterDuff.Mode 公式
PorterDuff.Mode.CLEAR alpha_{out} = 0
C_{out} = 0
PorterDuff.Mode.SRC alpha_{out} = alpha_{src}
C_{out} = C_{src}
PorterDuff.Mode.DST alpha_{out} = alpha_{dst}
C_{out} = C_{dst}
PorterDuff.Mode.SRC_OVER alpha_{out} = alpha_{src} + (1 - alpha_{src}) * alpha_{dst}
C_{out} = C_{src} + (1 - alpha_{src}) * C_{dst}
PorterDuff.Mode.DST_OVER alpha_{out} = alpha_{dst} + (1 - alpha_{dst}) * alpha_{src}
C_{out} = C_{dst} + (1 - alpha_{dst}) * C_{src}
PorterDuff.Mode.SRC_IN alpha_{out} = alpha_{src} * alpha_{dst}
C_{out} = C_{src} * alpha_{dst}
PorterDuff.Mode.DST_IN alpha_{out} = alpha_{src} * alpha_{dst}
C_{out} = C_{dst} * alpha_{src}
PorterDuff.Mode.SRC_OUT alpha_{out} = (1 - alpha_{dst}) * alpha_{src}
C_{out} = (1 - alpha_{dst}) * C_{src}
PorterDuff.Mode.DST_OUT alpha_{out} = (1 - alpha_{src}) * alpha_{dst}
C_{out} = (1 - alpha_{src}) * C_{dst}
PorterDuff.Mode.SRC_ATOP alpha_{out} = alpha_{dst}
C_{out} = alpha_{dst} * C_{src} + (1 - alpha_{src}) * C_{dst}
PorterDuff.Mode.DST_ATOP alpha_{out} = alpha_{src}
C_{out} = alpha_{src} * C_{dst} + (1 - alpha_{dst}) * C_{src}
PorterDuff.Mode.XOR alpha_{out} = (1 - alpha_{dst}) * alpha_{src} + (1 - alpha_{src}) * alpha_{dst}
C_{out} = (1 - alpha_{dst}) * C_{src} + (1 - alpha_{src}) * C_{dst}
PorterDuff.Mode.DARKEN alpha_{out} = alpha_{src} + alpha_{dst} - alpha_{src} * alpha_{dst}
C_{out} = (1 - alpha_{dst}) * C_{src} + (1 - alpha_{src}) * C_{dst} + min(C_{src}, C_{dst})
PorterDuff.Mode.LIGHTEN alpha_{out} = alpha_{src} + alpha_{dst} - alpha_{src} * alpha_{dst}
C_{out} = (1 - alpha_{dst}) * C_{src} + (1 - alpha_{src}) * C_{dst} + max(C_{src}, C_{dst})
PorterDuff.Mode.MULTIPLY alpha_{out} = alpha_{src} * alpha_{dst}
C_{out} = C_{src} * C_{dst}
PorterDuff.Mode.SCREEN alpha_{out} = alpha_{src} + alpha_{dst} - alpha_{src} * alpha_{dst}
C_{out} = C_{src} + C_{dst} - C_{src} * C_{dst}
PorterDuff.Mode.ADD alpha_{out} = max(0, min(alpha_{src} + alpha_{dst}, 1))
C_{out} = max(0, min(C_{src} + C_{dst}, 1)
PorterDuff.Mode.OVERLAY alpha_{out} = alpha_{src} + alpha_{dst} - alpha_{src} * alpha_{dst}
C_{out} = \begin{cases} 2 * C_{src} * C_{dst} & 2 * C_{dst} \lt \alpha_{dst} \\ alpha_{src} * \alpha_{dst} - 2 (\alpha_{dst} - C_{src}) (\alpha_{src} - C_{dst}) & otherwise \end{cases}

各種模式下的效果如下圖所示:

  • 1吐咳、如果原圖和目標(biāo)圖大小一致(圖中逻悠,兩者大小均占滿整個小方格區(qū)域):


    image.png
  • 2、如果原圖和目標(biāo)圖大小不一致(圖中韭脊,兩者大小為可見大型恕):


    image.png

這里可以發(fā)現(xiàn),兩種效果是不一樣的沪羔,谷歌官方給的是第一種饥伊,但是,通常情況應(yīng)該是第二種蔫饰,具體原因可參考該文章琅豆。比如我們畫一個矩形,應(yīng)該按第二種效果來考慮死嗦,因為源圖和目標(biāo)圖大小不一致趋距;如果畫相同大小的Bitmap,則按第一種做越除。

在實際應(yīng)用中节腐,我們可以從以下三個方面來決定使用哪種模式:

1、目標(biāo)圖像和源圖像混合摘盆,需不需要生成顏色的疊加特效翼雀。如果需要,則從顏色疊加相關(guān)模式中選擇孩擂,有Mode.ADD(飽和度相加)狼渊、Mode.DARKEN(變暗)、Mode.LIGHTEN(變亮)、Mode.MULTIPLY (正片疊底)狈邑、Mode.OVERLAY(疊加)城须、Mode.SCREEN(濾色)。
2米苹、當(dāng)不需要特效糕伐,而需要根據(jù)某張圖片的透明像素來裁剪時,就需要使用SRC相關(guān)模式或DST相關(guān)模式了蘸嘶。而SRC相關(guān)模式與DST相關(guān)模式是相通的良瞧,唯一不同的是決定當(dāng)前哪個圖像是目標(biāo)圖像和源圖像。
3训唱、當(dāng)需要清空圖像時褥蚯,使用Mode.CLEAR模式。

1.1况增、實例:

二赞庶、硬件加速

2.1、View的繪制模型

1巡通、沒有硬件加速:
invalidate the view hierarchy ------> draw the view hierarchy

2尘执、有硬件加速:
invalidate the view hierarchy ------> record and update the display list ------> draw the display list

2.2、開啟硬件加速后的異常

1宴凉、繪制不正確:可能使用了不支持硬件加速的操作, 需要關(guān)閉硬件加速或者繞過該操作
2表悬、拋出異常:可能使用了不支持硬件加速的操作弥锄, 需要關(guān)閉硬件加速或者繞過該操作

2.3、禁用GPU硬件加速

在Android系統(tǒng)中蟆沫,有4個不同級別的打開或者關(guān)閉硬件加速操作:

1籽暇、Application級別:
<application android:hardwareAccelerated="false">
默認(rèn)為true,用于控制這個app是否開啟硬件加速饭庞。

2戒悠、Activity級別:
<activity android:hardwareAccelerated="false">

3、Window級別:(只支持開啟操作)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

4舟山、View級別:(只支持關(guān)閉操作)
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
LAYER_TYPE_HARDWARE绸狐,使用硬件加速(GPU)進(jìn)行繪制
LAYER_TYPE_SOFTWARE,使用CPU進(jìn)行繪制

或者布局文件中累盗,指定以下屬性:
android:layerType="software"

2.4寒矿、檢測是否開啟硬件加速

1、view.isHardwareAccelerated()
如果返回true若债,表示view掛在一個開啟了硬件加速的Window之下符相,也就意味著,它在繪制時蠢琳,并不一定開啟了硬件加速啊终。
2镜豹、canvas.isHardwareAccelerated()
如果返回true,因為著canvas在繪制的時候啟用了硬件加速蓝牲,盡量采用此方法來判斷是否開啟了硬件加速趟脂。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搞旭,隨后出現(xiàn)的幾起案子散怖,更是在濱河造成了極大的恐慌,老刑警劉巖肄渗,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镇眷,死亡現(xiàn)場離奇詭異,居然都是意外死亡翎嫡,警方通過查閱死者的電腦和手機(jī)欠动,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惑申,“玉大人具伍,你說我怎么就攤上這事∪ν眨” “怎么了人芽?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绩脆。 經(jīng)常有香客問我萤厅,道長,這世上最難降的妖魔是什么靴迫? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任惕味,我火速辦了婚禮,結(jié)果婚禮上玉锌,老公的妹妹穿的比我還像新娘名挥。我一直安慰自己,他們只是感情好主守,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布禀倔。 她就那樣靜靜地躺著,像睡著了一般丸逸。 火紅的嫁衣襯著肌膚如雪蹋艺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天黄刚,我揣著相機(jī)與錄音捎谨,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛涛救,可吹牛的內(nèi)容都是我干的畏邢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼检吆,長吁一口氣:“原來是場噩夢啊……” “哼舒萎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹭沛,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤臂寝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后摊灭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咆贬,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年帚呼,在試婚紗的時候發(fā)現(xiàn)自己被綠了掏缎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡煤杀,死狀恐怖眷蜈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沈自,我是刑警寧澤酌儒,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站枯途,受9級特大地震影響今豆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柔袁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望异逐。 院中可真熱鬧捶索,春花似錦、人聲如沸灰瞻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酝润。三九已至燎竖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間要销,已是汗流浹背构回。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纤掸。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓脐供,卻偏偏與公主長得像,于是被迫代替她去往敵國和親借跪。 傳聞我的和親對象是個殘疾皇子政己,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容