Palette API を使用した色の選択

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

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

ライブラリを設定する

パレット ライブラリを使用するには、Android Support Library をインストールするか、またはバージョン 24.0.0 以上にアップデートし、Support Library の追加の手順に沿ってパレット ライブラリをアプリ開発プロジェクトに追加します。

依存関係識別子に指定されているバージョンが build.gradle ファイルで設定したアプリの compileSdkVersion と一致していることを確認してください。

    android {
      compileSdkVersion 28
      ...
    }

    dependencies {
      ...
      implementation 'com.android.support:palette-v7:28.0.0'
    }
    

注: Android Plugin for Gradle 3.0.0 以上を使用している場合は、「implementation」キーワードを使用します。それ以外のバージョンの Android Plugin for Gradle を使用している場合は、「compile」キーワードを使用します。

パレットの依存関係の追加方法について詳しくは、サポート ライブラリのドキュメントでパレット機能についての説明をご覧ください。

パレットを作成する

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

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

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

Palettefrom(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 の処理時間が長くなります。

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

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

Palette の各 get<Profile>Color() メソッドは、特定のプロファイルに関連付けられているパレット内の色を返します(ここで、<Profile> は 6 つのカラー プロファイルのいずれかの名前です)。たとえば、「暗いビブラント」カラー プロファイルを取得するメソッドは 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 でないことを確認する必要があります。たとえば、次のコードは、ビブラントの見本が 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 is not 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 code snippet above
        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);
    }
    

図 2. ビブラントの色を使用したツールバーとそれに対応するタイトル テキストの色を示すサンプル画像