新聞中心
一、前言

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了保德免費(fèi)建站歡迎大家使用!
今天介紹一個(gè) Android 下比較有意思的 Support v7 庫,Palette,它翻譯過來就是調(diào)色板。
Palette 可以從一張 Bitmap 中提取出它突出的顏色,這樣我們就可以將提取出來的顏色設(shè)置在 App 的固定 UI 中(例如:ToolBar 的背景),使得 UI 頁面的整體風(fēng)格更加的美觀和融洽。
比如,對(duì)于一些影視類的 App,視頻詳情頁的主題都是視頻的海報(bào),那么對(duì)于頁面背景,我們可以提取視頻海報(bào)的顏色,設(shè)置在背景上,使得效果更佳柔和美觀。
Palette 是一個(gè) Support v7 的包,如果使用 Gradle 引入依賴,這里使用***的 26.+。
- compile "com.android.support:palette-v7:26.+"
二、Palette 的使用
Palette 使用起來非常的簡(jiǎn)單,既然目的是從一個(gè)圖片中提取顏色,它的步驟就有:
- 傳遞一個(gè) Bitmap,得到一個(gè) Palette。
- 通過 Palette 提取需要的顏色。
就是這么簡(jiǎn)單,如同要將大象放冰箱,需要幾步一樣清晰。
那么接下來我們先來了解它使用的細(xì)節(jié)。
2.1 傳遞 Bitmap 得到一個(gè) Palette
Palette 在舊版本上有一些 generate() 的方法,用于生成一個(gè) Palette 對(duì)象,但是在新版本上已經(jīng)被標(biāo)記為 @Depercated 了,所以這里不推薦使用。
而在新版上,推薦使用 Palette.Builder 來創(chuàng)建我們的 Palette 對(duì)象,我們可以通過 from() 方法使用它。
一般我們使用***個(gè)方法即可,直接傳遞進(jìn)去一個(gè) Bitmap 對(duì)象。得到 Builder 之后,我們還可以配置一些規(guī)則,但是一般我們不需要進(jìn)行額外的(后面會(huì)講到)。再通過 Builder.generate() 即可得到我們需要的 Palette 對(duì)象了。
2.2 通過 Palette 提取顏色
Palette 從圖片中提取的顏色,有很多選擇。這里又涉及到另外一個(gè)類,Swatch 。
Palette 可被提取的每個(gè)顏色,都被封裝成一個(gè) Swatch 對(duì)象,用來管理多種顏色。
這些 Swatch 有:
- DominantSwatch
- VibrantSwatch
- DarkVibrantSwatch
- LightVibrantSwatch
- MutedSwatch
- DarkMutedSwatch
- LightMutedSwatch
其實(shí)這些 Swatch,真的不太好解釋其意義,唯一特別一點(diǎn)的就是 DominantSwatch ,它是從圖片中提取的最突出的顏色。
這些 Swatch 在 Palette 都提供了對(duì)應(yīng)的 getXxx() 方法獲得。不過需要注意的是,這些 getXxx() 方法可能會(huì)得到一個(gè) null ,因?yàn)橛行╊伾菦]有的。
如果只是需要得到一個(gè)顏色值,Palette 同時(shí)也提供了對(duì)應(yīng)的 getXxxColor() 方法,方便我們使用。
得到 Swatch 對(duì)象之后,就可以通過對(duì)應(yīng)的 Swatch 中對(duì)應(yīng)的 Api 獲取我們需要的顏色值。
- getPopulation() :Swatch 中的像素個(gè)數(shù)。
- getRgb():顏色的 RGB 值。
- getHsl():顏色的 HSL 值。
- getBodyTextColor():對(duì)應(yīng)的文字顏色值。
- getTitleTextColor():對(duì)應(yīng)的標(biāo)題文字顏色值。
通常來說,我們只需要通過 getRgb() 獲取到對(duì)應(yīng)的顏色設(shè)置在背景上,如果背景之上還有文字內(nèi)容,可以通過 getBodyTextColor() 提取出與背景匹配的文字顏色值,這樣可以顯得更加的柔和,讓文字看起來更清晰和舒服。比如,如果一個(gè)深色的背景,為它設(shè)置一個(gè)默認(rèn)的深色文字,基本上就看不見了,因?yàn)閷?duì)比對(duì)太弱。
2.3 舉個(gè)例子
到這里,基本上 Palette 的基本 Api 就講解清楚了,下面舉個(gè)實(shí)際的例子來看看。
這里找了三張 Eason 的海報(bào),用于做 Palette 的 Demo 資源,間隔去替換圖片,然后分別提取出對(duì)應(yīng)的顏色和字體顏色,設(shè)置在下面按鈕的背景上,然后每 3s 切換一張圖片。
因?yàn)橛幸恍﹫D片,獲取的 Swatch 可能會(huì)返回 null ,所以這里用了一個(gè)比價(jià)扎眼的紅色,作為錯(cuò)誤色。
以下是獲取 Swatch 的代碼。
接下來通過 Swatch 提取我們需要的顏色。
這里分別獲取了需要的顏色以及字體顏色,下面看看運(yùn)行的效果:
可以看到,確實(shí)有一些顏色,被標(biāo)記成了紅色,說明當(dāng)前圖片有獲取不到的對(duì)應(yīng)顏色。
三、分析 Palette 的實(shí)現(xiàn)
3.1 Palette 的主線邏輯
繼續(xù)深入看看 Palette 的實(shí)現(xiàn)原理,先從主線開始看。
從 Builder.generate() 開始。
從代碼中可以看到,在 generate() 中,主線邏輯:
- 首先會(huì)通過 scaleBitmapDown() 方法,將圖片壓縮成一個(gè)小像素的,等于生成了一個(gè)新的 Bitmap 對(duì)象,這樣有利于內(nèi)存的管理,并且也減少了計(jì)算量。
- 然后再通過 mRegion 判斷是否只是提取圖片的某個(gè)區(qū)域,默認(rèn)是完整的圖片全部提取,當(dāng)然也可以對(duì) mRegion 進(jìn)行配置。
- 之后再構(gòu)造一個(gè) ColorCutQuantizer 對(duì)象,使用它的 getQuantizedColors() 方法得到 Swatch。
- 使用完前面壓縮的 Bitmap 對(duì)象之后,再使用 recycle() 將其回收掉。
- ***,通過 Palette 本身的構(gòu)造函數(shù),去生成一個(gè) Palette 對(duì)象,返回出去。
接下來看看比較關(guān)鍵的 ColorCutQuantizer 中的實(shí)現(xiàn)邏輯。
從代碼中可以看到,其中的邏輯還是很清晰的。
- 首先通過 quantizeFromRgb888() 方法,將每個(gè)像素的顏色進(jìn)行量化,類似于將每個(gè)顏色取一個(gè)靠近的設(shè)置。舉個(gè)不恰當(dāng)?shù)睦?,將不同深度的紅,都標(biāo)記成紅色。
- 再通過 shouldIgnoreColor() 過濾掉不需要的顏色。
- 最終獲取到的顏色,如果小于等于我們?cè)O(shè)置的 maxColors,就可以通過approximateToRgb888() 生成一批 Swatch。
- 如果大于 maxColors,就再通過 quantizePixels() 去掉一些雜色。
- 無論如何,最終操作的就是這里得到的 mQuantizedColors 對(duì)象。
3.2 Swatch 的 Target
所有需要的 Swatch ,都是被 Target 對(duì)象所標(biāo)記。不同的 Swatch 都是通過 Target 中標(biāo)記的常量值,進(jìn)行運(yùn)算,得到行的顏色。
3.3 過濾掉不需要的顏色
Palette 可以設(shè)置一些我們不需要的顏色,讓它們不參與運(yùn)算。這里的過濾條件,通過 Filter 來設(shè)定,并且 Palette 也提供給了一個(gè) DEFAULT_FALTER 來標(biāo)記默認(rèn)的過濾顏色。
可以看到,默認(rèn)的 Filter 會(huì)過濾掉一些靠近黑和白的顏色。
當(dāng)然,我們也可以自己定義 Filter ,并通過 Palette 中的 addFilter()、clearFilters() 來管理它。
這里存儲(chǔ) Filter 的是一個(gè) ArrayList ,所以我們是可以定義很多個(gè) Filter 加入進(jìn)去的,它們都會(huì)生效。
3.4 設(shè)置 MaxColor
在 ColorCutQuantizer 中,被使用的 maxColor ,主要用于標(biāo)記需要使用的顏色個(gè)數(shù)。它是可以通過 maximumColorCount() 方法,進(jìn)行設(shè)置的,如果不對(duì)其進(jìn)行設(shè)定,默認(rèn)值為 16。
理論上來說,這里設(shè)置的maxColor 的值越大,運(yùn)算花費(fèi)的時(shí)間就越長。而越小,可以被選擇的色值也就越少。
所以***的做法是根據(jù)當(dāng)前 Bitmap 的用途來決定,色彩越豐富的圖,設(shè)置的 maxColor 越大,即可。不過正常來說也不需要額外的設(shè)定,默認(rèn)的配置就挺好用了。
四、小結(jié)
到這里就分析完 Palette 的所有相關(guān)的內(nèi)容,不要僅僅滿足使用。實(shí)際上看了 Palette 的源碼,對(duì)色彩的運(yùn)算,也有了更加深入的了解。
【本文為專欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過微信公眾號(hào)聯(lián)系作者獲取授權(quán)】
戳這里,看該作者更多好文
當(dāng)前題目:使用Palette使你的UI色彩與內(nèi)容更貼合
路徑分享:http://www.5511xx.com/article/djidiod.html


咨詢
建站咨詢
