ZOFTINO.COM android and web dev tutorials

Extracting Color Codes from Image Using Android Palette API

Using android palette API, color codes of dominant colors can be extracted from an image. The main use of this API is that layout theme or color of visual elements can be dynamic and matched to one of the prominent colors of the selected image.

For examples, in the shopping app, when user views details of a product, color of status bar, action bar and UI widgets can be changed to the colors from the product image.

extracting colors from image and applying them to ui elements using android palette api example

Setup

To use Palette API, following library needs to be added to build.gradle file.

implementation 'com.android.support:palette-v7:28.0.0'

Android Palette API

The main class in the Palette API used for extracting colors from an image is Palette. To create a Palette object, first Palette.Builder needs to be created passing the image from which colors need to be extracted as bitmap to its constructor.

        Palette.Builder pb = new Palette.Builder(bitMap);

Palette.Builder has various methods such as setRegion, resizeBitmapArea, resizeBitmapSize to change the behavior of color extractor, call those methods as required. Then call generate() method on Palette.Builder to create Palette object which contains extracted color codes.

Palette.Builder pb = new Palette.Builder(bitMap);
Palette palette = pb.generate();

Palette.Builder object can also be create using from() method of Palette.

Palette p = Palette.from(getBitMap(index)).generate();

Palette object can be generated both synchronously and asynchronously. Palette object should not be created on the main thread. Following code shows how to create Palette asynchronously.

Palette.from(bitmap).generate(new PaletteAsyncListener() {
    public void onGenerated(Palette p) {
           Log.d("Palette", "no of colors "+p.getSwatches().size());
    }
});

Palette API extracts Light Vibrant, Vibrant, Dark Vibrant, Light Muted, Muted, Dark Muted colors which can be obtained from Palette object by calling corresponding color method and applied to UI elements.

int actionbarColor = palette.getDarkMutedColor(
        getResources().getColor(R.color.colorPrimaryDark, null));
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(actionbarColor));

Palette object contains Swatch for each color. Swatch contains information about color profile.

Palette.Swatch dominantSwatch = palette.getDominantSwatch();
int bodyTextColor = dominantSwatch.getBodyTextColor();
int titleTextColor = dominantSwatch.getTitleTextColor();
int color = dominantSwatch.getRgb();

Android Palette API Example

Let’s see how to use Palette API to extract colors from images and use them to change the color of the UI elements using shopping app. The example app has two screens, one displays list of products and second screen displays product details. Colors from the image of the selected product are extracted using Palette API and applied to UI elements such as status bar, action bar and button on the product details screen.

android palette api example

Product List Activity

public class ProductsListActivity extends AppCompatActivity {
    private ListView products;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.products_list);

        products = findViewById(R.id.products);

        products.setAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, ProductsData.prepareProductsList()));

        products.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(ProductsListActivity.this,
                        ProductDetailsActivity.class);
                intent.putExtra("prdIndex", position);
                startActivity(intent);
            }
        });
    }
}

Product Details Activity

public class ProductDetailsActivity extends AppCompatActivity {

    private Button add;
    private Button buy;
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.product_details);

        int index = (Integer) getIntent().getExtras().get("prdIndex");

        tv = findViewById(R.id.prodTitle);
        tv.setText(ProductsData.prepareProductsList().get(index));

        ImageView iv = findViewById(R.id.productImage);
        iv.setImageResource(ProductsData.preparePrdImageList().get(index));

        add = findViewById(R.id.add);
        buy = findViewById(R.id.buy);

        setColors(index);
    }

    public void setColors(int index){

        Palette p = Palette.from(getBitMap(index)).generate();

        getSupportActionBar().setBackgroundDrawable(new ColorDrawable(p.getLightMutedColor(
                getResources().getColor(R.color.colorPrimaryDark, null))));

        this.getWindow().setStatusBarColor(p.getDominantColor(
                getResources().getColor(R.color.colorAccent, null)));

        buy.setBackgroundColor(p.getLightVibrantColor(
                getResources().getColor(R.color.colorAccent, null)));

        add.setBackgroundColor(p.getDarkMutedColor(
                getResources().getColor(R.color.colorAccent, null)));
    }

    public Bitmap getBitMap(int index){
        Drawable myDrawable = getResources().getDrawable(ProductsData.preparePrdImageList()
                .get(index), null);
        return ((BitmapDrawable) myDrawable).getBitmap();
    }
}

Product Details Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="8dp"
    tools:context=".ProductDetailsActivity">

    <TextView
        android:id="@+id/prodTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/productImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/prodTitle" />

    <Button
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Add to cart"
        style="@style/Widget.AppCompat.Button.Colored"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="@+id/buy"
        app:layout_constraintTop_toBottomOf="@+id/productImage" />

    <Button
        android:id="@+id/buy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Buy"
        style="@style/Widget.AppCompat.Button.Colored"
        app:layout_constraintLeft_toLeftOf="@+id/add"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/productImage" />
</android.support.constraint.ConstraintLayout>