1. 程式人生 > >【譯】在Android Lollipop中使用Palette抽取Bitmap顏色

【譯】在Android Lollipop中使用Palette抽取Bitmap顏色

在Android Lollipop中使用Palette抽取Bitmap顏色

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

Palette有一個用法我特別喜歡:它可以定製影象波紋的顏色。這是其實一個微不足道的效果,但是 我認為相比於純灰色波紋來說是一個很大的提升。你需要在工程下的build.gradle裡新增依賴才可以使用Palette,像如下程式碼所示:

dependencies {
  compile 'com.android.support:palette-v7:21.0.0'
}

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

  • generate(Bitmap) 生成含有16種顏色種類的Palette;
  • generate(Bitmap, int) 生成含有指定數量顏色種類的Palette,數量越多需要的時間越久。

這兩個方法是同步方法,由於他們很可能會比較耗時(在分析大圖片或者所需顏色較多時),所以他們不應該在主執行緒中執行。你應該在別的執行緒中執行,在載入完顏色之後再使用它。

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

  • generateAsync(Bitmap, PaletteAsyncListener)
  • generateAsync(Bitmap, int, PaletteAsyncListener)

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

Palette.PaletteAsyncListener listener = new Palette.PaletteAsyncListener() {
  public void onGenerated(Palette palette) {
    // access palette colors here
  }
}

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

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

這是一個Palette解析六個主顏色種類的例子:

Six Color

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

Palette palette = Palette.generate(myBitmap);
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);

Swatch

這些顏色都來自於對應的Swatch,在Swatch裡面含有很多關於對應顏色的有用資訊。你可以從Swatch中獲取RGB顏色值、HSV顏色值、對應顏色在影象中所佔的比例、與對應顏色搭配的標題字型顏色和正文字型顏色(這兩個顏色和對應顏色的對比值是處理好的,你不必再去操心)。如下面這段程式碼所示:

Palette palette  = Palette.generate(myBitmap);
Palette.Swatch swatch = palette.getVibrantSwatch();
int rgbColor = swatch.getRgb();
float[] hslValues = swatch.getHsl();
int pixelCount = swatch.getPopulation();
int titleTextColor = swatch.getTitleTextColor();
int bodyTextColor = swatch.getBodyTextColor();

獲取六個主顏色的Swatch要使用與之前直接獲取顏色不同的getter函式,如下面這部分程式碼所示。它們不需要提供預設值,如果Palette沒有解析到對應顏色種類,它會直接返回null。

Palette palette = Palette.generate(myBitmap);
Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
Palette.Swatch vibrantLightSwatch = palette.getLightVibrantSwatch();
Palette.Swatch vibrantDarkSwatch = palette.getDarkVibrantSwatch();
Palette.Swatch mutedSwatch = palette.getMutedSwatch();
Palette.Swatch mutedLightSwatch = palette.getLightMutedSwatch();
Palette.Swatch mutedDarkSwatch = palette.getDarkMutedSwatch();

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

這裡是一個Palette獲取所有Swatch的例子,裡面展示了它們分別在影象中所佔的比例:

all color

Palette的非同步方法使得它非常容易去使用,而且我也看到了它用在很多地方。它真是一個非常棒的工具,能夠收集一幅圖中所有的顏色,並將它們總結到幾個不同種類的顏色中。我建議你閱讀原始碼來更多地學習它!