WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

Android Support Libraryの「Palette」を使って色を抽出する

今回のエンジニアブログ担当の佐藤です

今回は、AndroidのSupport Libraryに追加されたPaletteという機能があると知り、早速使ってみましたのでご紹介したいと思います。
Palette(パレット)とは、指定した画像の中から色の解析をし、自動で鮮やかな色,落ち着き目の色をそれぞれ3段階、計6色に分けてくれる機能です。

Paletteはandroid.support.v7.graphics.Paletteというクラスを使用します。
現状support-v7とは別にインポートしないといけないようです。
build.gradleのdependenciesに追記をしました。

[build.gradle]
compile 'com.android.support:palette-v7:+'
次に、MainActivityに抽出対象の画像のBitmapを用意し、Paletteで色の抽出を行います。

MainActivity.java

import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.os.Bundle;  
import android.support.v7.app.ActionBarActivity;  
import android.support.v7.graphics.Palette;  
import android.widget.TextView;  
  
public class MainActivity extends ActionBarActivity {  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
  
        // 色を抽出する画像(Bitmap)  
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sky);  
  
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {  
            public void onGenerated(Palette palette) {  
                if  (palette != null) {  
                    // VibrantSwatch  
                    TextView vibrant_swatch = (TextView)findViewById(R.id.vibrant_swatch);  
                    vibrant_swatch.setBackgroundColor(palette.getVibrantSwatch().getRgb());  
                    vibrant_swatch.setTextColor(palette.getVibrantSwatch().getTitleTextColor());  
  
                    TextView dark_vibrant_swatch = (TextView)findViewById(R.id.dark_vibrant_swatch);  
                    dark_vibrant_swatch.setBackgroundColor(palette.getDarkVibrantSwatch().getRgb());  
                    vibrant_swatch.setTextColor(palette.getDarkVibrantSwatch().getTitleTextColor());  
  
                    TextView light_vibrant_swatch = (TextView)findViewById(R.id.light_vibrant_swatch);  
                    light_vibrant_swatch.setBackgroundColor(palette.getLightVibrantSwatch().getRgb());  
                    light_vibrant_swatch.setTextColor(palette.getLightVibrantSwatch().getTitleTextColor());  
  
                    //MutedSwatch  
                    TextView muted_swatch = (TextView)findViewById(R.id.muted_swatch);  
                    muted_swatch.setBackgroundColor(palette.getMutedSwatch().getRgb());  
                    muted_swatch.setTextColor(palette.getMutedSwatch().getTitleTextColor());  
  
                    TextView dark_muted_swatch = (TextView)findViewById(R.id.dark_muted_swatch);  
                    dark_muted_swatch.setBackgroundColor(palette.getDarkMutedSwatch().getRgb());  
                    dark_muted_swatch.setTextColor(palette.getDarkMutedSwatch().getTitleTextColor());  
  
                    TextView light_muted_swatch = (TextView)findViewById(R.id.light_muted_swatch);  
                    light_muted_swatch.setBackgroundColor(palette.getLightMutedSwatch().getRgb());  
                    light_muted_swatch.setTextColor(palette.getLightMutedSwatch().getTitleTextColor());  
  
                }  
            }  
        });  
    }  
}  

レイアウト
activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:padding="10dp"  
    tools:context=".MainActivity">  
    <ImageView  
        android:id="@+id/image"  
        android:src="@drawable/sky"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_centerHorizontal="true"/>  
    <LinearLayout  
        android:padding="10dp"  
        android:layout_below="@id/image"  
        android:orientation="vertical"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content">  
  
        <TextView  
        android:padding="5dp"  
        android:id="@+id/vibrant_swatch"  
        android:text="VibrantSwatch"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" />  
        <TextView  
            android:padding="5dp"  
            android:id="@+id/dark_vibrant_swatch"  
            android:text="DarkVibrantSwatch"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content" />  
        <TextView  
            android:padding="5dp"  
            android:id="@+id/light_vibrant_swatch"  
            android:text="LightVibrantSwatch"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content" />  
  
        <TextView  
            android:padding="5dp"  
            android:id="@+id/muted_swatch"  
            android:text="MutedSwatch"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content" />  
        <TextView  
            android:padding="5dp"  
            android:id="@+id/dark_muted_swatch"  
            android:text="DarkMutedSwatch"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content" />  
        <TextView  
            android:padding="5dp"  
            android:id="@+id/light_muted_swatch"  
            android:text="LightMutedSwatch"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content" />  
    </LinearLayout>  
</RelativeLayout>  
  

抽出された色はそれぞれTextViewの背景に設定しました。

それぞれ以下のように自動で抽出してくれます。

  • getVibrantSwatch().getRgb()
    画像の色
  • getVibrantSwatch().getTitleTextColor()
    画像の色の上に乗せるタイトルに合う文字色
  • getVibrantSwatch.getBodyTextColor()
    画像の色の上に乗せる本文に合う文字色

画像の取り込みにはPalette.generate()とPalette.generateAsync()があるようです。
今回はメインスレッドで使うということもあり、Palette.generateAsync()の方を使用しました。

実行するとこんな感じになります

Screenshot_2015-04-20-21-36-26
見事に色を抽出してくれました!

結構お手軽にできるので、配色に困ったときなんかは便利なのではないかと思いました。