Android-使用 SetColorFilter 神奇地改變圖片的顏色

無(wú)意中 Get 一個(gè)新技能

公司的移動(dòng)端應(yīng)用,最近要換一個(gè) UI 主題色,在更換一個(gè)圖片控件的選中與未選中效果時(shí),本以為需要 UI 配合給新顏色切圖的,然而并不是,直接使用 setColorFilter() 改顏色就好了。

無(wú)知的我很開(kāi)心 get 了一個(gè)新技能!

這件小事的詳情

現(xiàn)在,有一個(gè)效果展示是這樣的,選中某個(gè)車(chē)型時(shí),顯示選中的顏色,是主題色紅色。

image

現(xiàn)在,我們的產(chǎn)品和UI寶寶決定要把主題色改成藍(lán)色,于是選中效果要像下面這樣:

image

看項(xiàng)目代碼的時(shí)候,然后很驚訝的發(fā)現(xiàn)圖片的原圖,是這個(gè)樣子的:

image

樣式布局:

//UI布局
<ImageView
    android:id="@+id/icon"
    android:layout_width="85dp"
    android:layout_height="38dp"
    android:layout_marginTop="5dp"
    tools:src="@drawable/icon_carlevel_race"
    android:scaleType="fitCenter" />

代碼控制顏色顯示:


//定義選中的顏色
int checkColor = context.getResources().getColor(R.color.theme_red);

//當(dāng)選中該項(xiàng)時(shí),顯示選中顏色,否則顯示未選中顏色
viewHolder.icon.setColorFilter(selectPosition==position? checkColor :Color.TRANSPARENT);

于是針對(duì)這個(gè)控件改顏色的需求,就只需要修改 checkColor 修改成藍(lán)色就好了,這神奇的操作在很明顯在于 setColorFilter 這個(gè)方法,于是我點(diǎn)擊進(jìn)去,看到源碼中這個(gè)方法的實(shí)現(xiàn)。

/**
 * Set a tinting option for the image. Assumes
 * {@link PorterDuff.Mode#SRC_ATOP} blending mode.
 *
 * @param color Color tint to apply.
 * @attr ref android.R.styleable#ImageView_tint
 */
@RemotableViewMethod
public final void setColorFilter(int color) {
    setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}

注釋說(shuō)明該方法可為 ImageView 設(shè)置著色選項(xiàng)。內(nèi)部實(shí)現(xiàn)是調(diào)用了該方法的重載方法,默認(rèn)參數(shù)是 PorterDuff.Mode.SRC_ATOP,圖形混合渲染模型之一,此參數(shù)是圖片改變顏色實(shí)現(xiàn)的重點(diǎn),下面簡(jiǎn)單介紹一下。

PorterDuff.Mode

PorterDuff,一個(gè)陌生的單詞,百度翻譯和谷歌翻譯都查無(wú)來(lái)處,原因在于它是一個(gè)組合詞匯,來(lái)源于 Tomas Proter(托馬斯波特)和 Tom Duff(湯姆達(dá))兩個(gè)名字。這倆人是在圖形混合方面的大神級(jí)人物,他們?cè)?1984 年發(fā)表了論文,第一次提出了圖形混合的概念,也是取了兩人的名字命名。

Android PorterDuff.Mode 便是提供了圖片的各種混合模式,可以分為兩類(lèi):

  • Alpha compositing modes(由倆大神的定義,包含 alpha 通道因素)
  • Blending modes(不是倆大神的作品,不包含 alpha 通道因素)

具體的可以看官方文檔對(duì) PorterDuff.Mode
的介紹,我這里只說(shuō)涉及到的 SRC_ATOP。

既然混合,兩個(gè)圖片,源圖片和目標(biāo)圖片,如下:

image

SRC_ATOP 混合模式效果如下圖,只保留源圖片和目標(biāo)圖片的相交部分,其他部分舍棄:

image

按照上面的示例來(lái)對(duì)應(yīng),那么我們的源圖就是藍(lán)色,目標(biāo)圖片是小汽車(chē)圖案。藍(lán)色和小汽車(chē)圖案的重合部分,只有線條,所以能達(dá)到改變顏色的效果。

那么,就算我們的小汽車(chē)圖片是任何顏色,都能達(dá)到不換圖片,改選中顏色的效果。

在這種簡(jiǎn)單的圖片顏色上,合理使用 SetColorFilter() ,可以為 UI 好搭檔節(jié)省了不少切圖工作量,而且,同樣能縮小了 APK 的體積。

最后

接手老項(xiàng)目的迭代開(kāi)發(fā),是十分奇妙的旅程,誰(shuí)知道下面等待著的是一個(gè)深坑還是華麗的騷操作。

see you next blog ~


歡迎關(guān)注博主的微信公眾號(hào),快快加入哦,期待與你一起成長(zhǎng)!
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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