1. 程式人生 > >Android Lollipop:使用Palette抽取圖片主色調

Android Lollipop:使用Palette抽取圖片主色調

轉載請註明:https://blog.csdn.net/u012854870/article/details/84790724

使用Palette抽取Bitmap主色調

關於Palette

一些Support庫隨著Android Lollipop的釋出而誕生了,其中就有Palette。這個庫可以讓你很輕鬆地從一幅圖中抽取特徵顏色,這在你希望介面的顏色風格適應指定圖片時非常有用,它還會提供與指定顏色相搭配的字型顏色。

Palette顧名思義調色盤, Palette的作用是可以從影象中提取圖片的顏色。我們可以把提取的顏色融入到App UI中,可以使UI風格更加美觀融洽。有些時候Palette顯得非常好用,比如我們可以提取到的突出的色值設定為Toolbar,標題,狀態列的顏色等,可以使我們的整個介面色調統一,效果非常好看。

開始使用

導包

你需要在工程下的build.gradle裡新增依賴才可以使用Palette,像如下程式碼所示:

compile 'com.android.support:palette-v7:27.1.1'

生成Palette

生成一幅影象的Palette有一下幾種方法:

 /**
     * 使用Glide獲取網路圖片並轉換為Bitmap
     *
     * @param path 圖片地址
     */
    private void asBitmap(String path) {
        Glide.with(HomeNewFragment.this).asBitmap()
                .load(path)
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition<? super Bitmap>
                            transition) {
                        paletteBitmap(bitmap);
                    }
                });
    }

    /**
     * 非同步抽取圖片色調方法
     *
     * @param bitmap Bitmap物件
     */
    private void paletteBitmap(@NonNull Bitmap bitmap) {
        Palette.from(bitmap)//建立Palette.Builder
                .generate(new Palette.PaletteAsyncListener() {//非同步抽取圖片色調方法
                    @Override
                    public void onGenerated(@NonNull Palette palette) {
                        //獲取到充滿活力的這種色調
                        Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
                        if (vibrantSwatch != null) {
                            Log.e("Zorro", "===vibrantSwatch=1=" + vibrantSwatch.getRgb());
                        }
                        //獲取充滿活力的黑
                        Palette.Swatch darkVibrantSwatch = palette.getDarkVibrantSwatch();
                        if (darkVibrantSwatch != null) {
                            Log.e("Zorro", "===darkVibrantSwatch=2=" + darkVibrantSwatch.getRgb());
                        }
                        //獲取充滿活力的亮
                        Palette.Swatch lightVibrantSwatch = palette.getLightVibrantSwatch();
                        if (lightVibrantSwatch != null) {
                            Log.e("Zorro", "===lightVibrantSwatch=3=" + lightVibrantSwatch.getRgb());
                        }
                        //獲取柔和的色調
                        Palette.Swatch mutedSwatch = palette.getMutedSwatch();
                        if (mutedSwatch != null) {
                            Log.e("Zorro", "===mutedSwatch=4=" + mutedSwatch.getRgb());
                            mBinding.testBg.setBackgroundColor(mutedSwatch.getRgb());
                        }
                        //獲取柔和的黑
                        Palette.Swatch darkMutedSwatch = palette.getDarkMutedSwatch();
                        if (darkMutedSwatch != null) {
                            Log.e("Zorro", "===darkMutedSwatch=5=" + darkMutedSwatch.getRgb());
                        }
                        //獲取柔和的亮
                        Palette.Swatch lightMutedSwatch = palette.getLightMutedSwatch();
                        if (lightMutedSwatch != null) {
                            Log.e("Zorro", "===lightMutedSwatch=6=" + lightMutedSwatch.getRgb());
                        }
                    }
                });
    }

非同步方法。有時候你不會在載入圖片的執行緒(非主執行緒)中使用解析出的顏色,所以Palette提供了非同步方法,他們與之前的函式的區別就是需要傳入PaletteAsyncListener,提供在圖片解析完成後的回撥函式。

PaletteAsyncListener的實現是非常簡單的(參考下面這幾行程式碼),它只要重寫onGenerated就好了。如此一來你就可以在任何需要的時候使用這兩個函式建立Palette。

Palette.PaletteAsyncListener listener = new Palette.PaletteAsyncListener() {
  public void onGenerated(Palette palette) {
    // 使用Palette物件,獲取解析出的顏色
  }
}

提取出的顏色

Palette預設會解析出影象的16種特徵顏色種類,但是這六種顏色是你最經常用到的:

  • vibrant(鮮豔色)
  • dark vibrant(鮮豔色中的暗色)
  • light vibrant(鮮豔色中的亮色)
  • muted(柔和色)
  • dark muted(柔和色中的暗色)
  • light muted(柔和色中的亮色)

獲取提取的顏色

你獲取Palette物件之後,可以通過以下這些內建getter函式直接獲取這六個顏色。你需要傳入預設顏色防止Palette無法解析到指定顏色種類,返回的型別是24位RGB顏色數值。

        //同步抽取圖片色調方式
        Palette palette = Palette.from(bitmap).generate();
        int vibrant = palette.getVibrantColor(0x000000);
        int vibrantLight = palette.getLightVibrantColor(0x000000);
        int vibrantDark = palette.getDarkVibrantColor(0x000000);
        int muted = palette.getMutedColor(0x000000);
        int mutedLight = palette.getLightMutedColor(0x000000);
        int mutedDark = palette.getDarkMutedColor(0x000000);
        //獨特的一種
        //返回從調色盤中占主導地位的樣本的顏色,為RGB包裝INT。
        int dominant = palette.getDominantColor(0x000000);

獲取Swatch

你也可以選擇先獲取Swatch物件,然後再通過Swatch提供的方法獲取顏色的相關資訊:

        Palette.Swatch s = palette.getVibrantSwatch();       //獲取到充滿活力的這種色調
        Palette.Swatch s = palette.getDarkVibrantSwatch();    //獲取充滿活力的黑
        Palette.Swatch s = palette.getLightVibrantSwatch();   //獲取充滿活力的亮
        Palette.Swatch s = palette.getMutedSwatch();           //獲取柔和的色調
        Palette.Swatch s = palette.getDarkMutedSwatch();      //獲取柔和的黑
        Palette.Swatch s = palette.getLightMutedSwatch();    //獲取柔和的亮
        //獨特的一種
        //返回從調色盤中占主導地位的樣本。
        Palette.Swatch s = palette.getDominantSwatch();

注意:getVibrantSwatch()可能會返回一個null值,所以在使用前檢查一下是必須的。if (swatch != null) {}

Palette解析出的顏色都來自於對應的Swatch,在Swatch裡面含有很多關於對應顏色的有用資訊。你可以從Swatch中獲取RGB顏色值、HSL顏色向量、對應顏色在影象中所佔的比例、與對應顏色搭配的標題字型顏色和正文字型顏色(這兩個顏色和對應顏色的對比值是處理好的,你不必再去操心)。

swatch物件對應的顏色方法:

getPopulation(): 畫素的數量
getRgb(): RGB顏色
getHsl(): HSL顏色
getBodyTextColor(): 用於內容正文文字的顏色
getTitleTextColor(): 標題文字的顏色

Palette只為七種主顏色種類Swatch提供了getter,如果你要使用其他顏色種類的Swatch(一共有16種顏色種類),你需要手動獲取它。呼叫getSwatchs()會返回一個列表,裡面有所有獲取到的Swatch。

List<Palette.Swatch> swatches = palette.getSwatches();

關於顏色種類的值size

Palette.from(bitmap).maximumColorCount(16);

生成Palette的時候,你可能注意到了可以設定Palette的size。size越大,花費的時間越長,而越小,可以選擇的色彩也越小。最佳的選擇是根據image的用途:

  • 頭像之類的,size最好在24-32之間;
  • 風景大圖之類的,size差不多在8-16;
  • 預設是16.

最後推薦大家一個三方庫

此庫是結合Glide實現的抽取圖片色調

地址:https://github.com/florent37/GlidePalette

 
Glide