Palette API を使用して色を選択する

優れた視覚デザインはアプリの成功に不可欠であり、カラーパターンはデザインの重要な要素です。Palette ライブラリは、画像から目立つ色を抽出して視覚的な魅力に富むアプリを作成するための Jetpack ライブラリです。

Palette ライブラリを使用すると、レイアウトのテーマを設計し、アプリのビジュアル エレメントにカスタムカラーを適用できます。たとえば、パレットを使用して、アルバムカバーに基づいて曲のタイトルカードの配色を決めたり、背景画像が変更されたときにアプリのツールバーの色を調整したりできます。Palette オブジェクトを使用すると、Bitmap 画像の色を操作できるほか、ビットマップの 6 つの主要なカラー プロファイルを通じてデザインの選択肢を提供することもできます。

ライブラリを設定する

Palette ライブラリを使用するには、build.gradle に以下を追加します。

Kotlin

android {
    compileSdkVersion(33)
    ...
}

dependencies {
    ...
    implementation("androidx.palette:palette:1.0.0")
}

Groovy

android {
    compileSdkVersion 33
    ...
}

dependencies {
    ...
    implementation 'androidx.palette:palette:1.0.0'
}

パレットを作成する

Palette オブジェクトでは、画像のメインカラーとその上に書かれたテキストの色を操作できます。パレットを使用すると、アプリのスタイルをデザインしたり、特定のソース画像に基づいてアプリのカラーパターンを動的に変更したりできます。

パレットを作成するには、まず、Bitmap から Palette.Builder をインスタンス化します。パレットを生成する前に、Palette.Builder を使用してパレットをカスタマイズできます。このセクションでは、ビットマップ画像からのパレットの作成とカスタマイズについて説明します。

Palette インスタンスを生成する

from(Bitmap bitmap) メソッドを使用して Palette インスタンスを生成し、まず Bitmap から Palette.Builder を作成します。

ビルダーは、パレットを同期または非同期で生成できます。呼び出されるメソッドと同じスレッドでパレットを作成する場合は、同期パレット生成を使用します。パレットを別のスレッドで非同期的に生成する場合は、onGenerated() メソッドを使用して、パレットが作成された直後にパレットにアクセスします。

次のコード スニペットは、これら 2 種類の方法でパレットを生成するメソッドの例を示しています。

Kotlin

// Generate palette synchronously and return it.
fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()

// Generate palette asynchronously and use it on a different thread using onGenerated().
fun createPaletteAsync(bitmap: Bitmap) {
    Palette.from(bitmap).generate { palette ->
        // Use generated instance.
    }
}

Java

// Generate palette synchronously and return it.
public Palette createPaletteSync(Bitmap bitmap) {
  Palette p = Palette.from(bitmap).generate();
  return p;
}

// Generate palette asynchronously and use it on a different thread using onGenerated().
public void createPaletteAsync(Bitmap bitmap) {
  Palette.from(bitmap).generate(new PaletteAsyncListener() {
    public void onGenerated(Palette p) {
      // Use generated instance.
    }
  });
}

画像またはオブジェクトの並べ替えリスト用にパレットを連続して作成する必要がある場合は、UI のパフォーマンス低下を防ぐために Palette インスタンスをキャッシュ保存することを検討してください。パレットはメインスレッド上に作成しないでください。

パレットをカスタマイズする

Palette.Builder を使用すると、作成されたパレット内の色の数、画像の中でビルダーがパレットを作成する際に使用する領域、パレットに含める色を選択することによってパレットをカスタマイズできます。たとえば、黒を除外したり、ビルダーでパレットを作成する際に画像の上半分だけを使用したりできます。

Palette.Builder クラスの以下のメソッドを使用すると、パレットのサイズと色を微調整できます。

addFilter()
このメソッドは、作成されるパレットで使用可能な色を指定するフィルタを追加します。独自の Palette.Filter を渡して isAllowed() メソッドを変更して、パレットから除外する色を指定します。
maximumColorCount()
このメソッドは、パレットに含まれる色の最大数を設定します。デフォルト値は 16 で、最適な値はソース画像によって決まります。風景画像の場合、最適な値の範囲は 8 ~ 16 です。一方、顔を含む画像の場合、通常は 24 ~ 32 です。色の数が増えると、Palette.Builder がパレットを作成するのにかかる時間が長くなります。
setRegion()
このメソッドは、パレットを作成する際にビルダーがビットマップのどの領域を使用するかを指定します。このメソッドは、ビットマップからパレットを作成する場合にのみ使用できます。このメソッドが元の画像に影響することはありません。
addTarget()
このメソッドを使用して Target カラー プロファイルをビルダーに追加することにより、独自のカラー マッチングを行うことができます。デフォルトの Target では不十分な場合、熟練したデベロッパーであれば、Target.Builder を使用して独自の Target を作成できます。

カラー プロファイルを抽出する

パレット ライブラリは、マテリアル デザインの標準に基づいて、一般的に使用されるカラー プロファイルを画像から抽出します。各プロファイルは Target で定義され、ビットマップ画像から抽出された色は、彩度、輝度、母集団(色で表されるビットマップのピクセル数)に基づいて各プロファイルに対してスコア付けされます。各プロファイルで、スコアが最も高い色によって特定の画像のカラー プロファイルが定義されます。

Palette オブジェクトにはデフォルトで、任意の画像の 16 のメインカラーが含まれています。パレットを作成する際には、Palette.Builder を使用して色の数をカスタマイズできます。抽出する色の数を増やすと、各カラー プロファイルが一致する可能性が高くなりますが、パレットを作成する際の Palette.Builder の処理時間が長くなります。

Palette ライブラリは、次の 6 つのカラー プロファイルの抽出を試みます。

  • 明るいビブラント
  • ビブラント
  • 暗いビブラント
  • 明るいミュート
  • ミュート
  • 暗いミュート

Palette の各 get<Profile>Color() メソッドは、特定のプロファイルに関連付けられているパレット内の色を返します(ここで、<Profile> は 6 つのカラー プロファイルのいずれかの名前です)。たとえば、Dark Vibrant カラー プロファイルを取得するメソッドは getDarkVibrantColor() です。すべての画像にすべてのカラー プロファイルが含まれるわけではないため、返すデフォルトの色を指定します。

図 1 は、1 枚の写真と、それに対応して get<Profile>Color() メソッドから返されるカラー プロファイルを示しています。

左側に夕日、右側に抽出されたカラーパレットを示す画像。
図 1. パレットのデフォルトの最大色数(16)での、画像と抽出されたカラー プロファイルの例。

見本を使用してカラーパターンを作成する

Palette クラスも各カラー プロファイルの Palette.Swatch オブジェクトを生成します。Palette.Swatch オブジェクトには、そのプロファイル用に関連付けられている色と、色の母集団(ピクセル単位)が格納されます。

見本には、カラー プロファイルに関する詳細情報(HSL 値、ピクセルの母集団など)にアクセスするための追加のメソッドが含まれます。見本を使用すると、getBodyTextColor() メソッドと getTitleTextColor() メソッドを使って、より包括的なカラーパターンとアプリテーマを作成できます。これらのメソッドは、見本の色に対して使用するのに適した色を返します。

Palette の各 get<Profile>Swatch() メソッドは、特定のプロファイルに関連付けられている見本を返します(<Profile> は 6 つのカラー プロファイルのいずれかの名前で置き換えられます)。パレットの get<Profile>Swatch() メソッドはデフォルト値パラメータを必要としませんが、特定のプロファイルが画像内に存在しない場合は null を返します。そのため、見本を使用する前に、その見本が null でないことを確認してください。たとえば次のコードは、Vibrant 見本が null でない場合、パレットからタイトルのテキストの色を取得します。

Kotlin

val vibrant = myPalette.vibrantSwatch
// In Kotlin, check for null before accessing properties on the vibrant swatch.
val titleColor = vibrant?.titleTextColor

Java

Palette.Swatch vibrant = myPalette.getVibrantSwatch();
if(vibrant != null){
    int titleColor = vibrant.getTitleTextColor();
    // ...
}

パレット内のすべての色にアクセスするには、 getSwatches() メソッドを使用して、画像から生成されたすべての見本のリスト(標準の 6 色プロファイルを含む)を返します。

次のコード スニペットでは、上記のコード スニペットのメソッドを使用して、パレットを同期的に生成し、鮮やかな色見本を取得して、ビットマップ画像に合わせてツールバーの色を変更します。図 2 に、結果として作成された画像とツールバーを示します。

Kotlin

// Set the background and text colors of a toolbar given a bitmap image to
// match.
fun setToolbarColor(bitmap: Bitmap) {
    // Generate the palette and get the vibrant swatch.
    val vibrantSwatch = createPaletteSync(bitmap).vibrantSwatch

    // Set the toolbar background and text colors.
    // Fall back to default colors if the vibrant swatch isn't available.
    with(findViewById<Toolbar>(R.id.toolbar)) {
        setBackgroundColor(vibrantSwatch?.rgb ?:
                ContextCompat.getColor(context, R.color.default_title_background))
        setTitleTextColor(vibrantSwatch?.titleTextColor ?:
                ContextCompat.getColor(context, R.color.default_title_color))
    }
}

Java

// Set the background and text colors of a toolbar given a bitmap image to
// match.
public void setToolbarColor(Bitmap bitmap) {
    // Generate the palette and get the vibrant swatch.
    // See the createPaletteSync() method from the preceding code snippet.
    Palette p = createPaletteSync(bitmap);
    Palette.Swatch vibrantSwatch = p.getVibrantSwatch();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

    // Load default colors.
    int backgroundColor = ContextCompat.getColor(getContext(),
        R.color.default_title_background);
    int textColor = ContextCompat.getColor(getContext(),
        R.color.default_title_color);

    // Check that the Vibrant swatch is available.
    if(vibrantSwatch != null){
        backgroundColor = vibrantSwatch.getRgb();
        textColor = vibrantSwatch.getTitleTextColor();
    }

    // Set the toolbar background and text colors.
    toolbar.setBackgroundColor(backgroundColor);
        toolbar.setTitleTextColor(textColor);
}
夕焼けと、TitleTextColor が設定されたツールバーを示す画像
図 2. ビブラントの色を使用したツールバーとそれに対応するタイトル テキストの色を示すサンプル画像