Android: Change background colour to match image palette

Visual design is the main aspect when it comes to designing views and layouts of any app. Android lollipop introduced Palette library that can be used to extract colors from the images. Pallette api can extract dark, light and muted colors. These colors can be used to change app color scheme like status bar, app bar, accent or background.

We will be using Glide library to asynchronously load images and also cache them. Once Glide loads the bitmap we can use Palette  api to extract the colors from the bitmap.

Glide and Palette Dependency

// Glide dependencies
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'

//
implementation "com.android.support:palette-v7:28.0.0"

Palette Color Extraction

Palette library can extract six color profiles and they are:

  • Light Vibrant – getLightVibrantColor()

  • Vibrant – getVibrantColor()

  • Dark Vibrant – getDarkVibrantColor()

  • Light Muted – getLightMutedColor()

  • Muted – getMutedColor()

  • Dark Muted – getDarkMutedColor()

These color profiles are illustrated in this image. I have taken an image for reference and created all six profiles to give you an idea of these color profiles.

Android palette color profiles

Android palette color profiles

 

Let’s see now how to extract color profiles using Palette api.

private void extractColorProfile(String imageUrl){
        GlideApp.with(this).asBitmap()
                .load(imageUrl)
                .into(new SimpleTarget<Bitmap>(){
                    @Override
                    public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                        mImageView.setImageBitmap(resource);
                        // Extract color
                        Palette.from(resource).generate(p -> {
                            int mutedLight = p.getLightMutedColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight2 = p.getMutedColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight3 = p.getDarkMutedColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight4 = p.getLightVibrantColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight5 = p.getVibrantColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight6 = p.getDarkVibrantColor(getResources().getColor(android.R.color.darker_gray));

                        });
                    }
                });
    }

Code to change background color

Create new Android Project with empty activity.

Create layouts for our activity.

activity_palette.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    tools:context="com.codeexa.com.firebaseexample.PaletteActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_palette" />

</android.support.design.widget.CoordinatorLayout>

content_palette.xml

<LinearLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:id="@+id/container"
    tools:context="com.codeexa.com.firebaseexample.palette.PaletteFragment">

<!-- TODO: Update blank fragment layout -->
<ImageView
    android:layout_gravity="top|center_horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="200dp"
    android:id="@+id/imageView"
    android:scaleType="centerCrop"
    android:contentDescription="@string/hello_blank_fragment" />

    <LinearLayout
        android:layout_marginTop="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <FrameLayout
            android:id="@+id/lightVibrantColor"
            android:layout_width="match_parent"
            android:layout_height="75dp">

            <TextView
                android:id="@+id/txtLightVibrantColor"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="Light Vibrant"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:textColor="@android:color/white" />
        </FrameLayout>
        <FrameLayout
            android:id="@+id/vibrantColor"
            android:layout_width="match_parent"
            android:layout_height="75dp">

            <TextView
                android:text="Vibrant"
                android:textColor="@android:color/white"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:layout_gravity="center"
                android:id="@+id/txtVibrantColor"/>
        </FrameLayout>

        <FrameLayout
            android:id="@+id/darkVibrantColor"
            android:layout_width="match_parent"
            android:layout_height="75dp">

            <TextView
                android:text="Dark Vibrant"
                android:textColor="@android:color/white"
                android:layout_width="wrap_content"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/txtDarkVibrantColor"/>
        </FrameLayout>
        <FrameLayout
            android:id="@+id/lightMutedColor"
            android:layout_width="match_parent"
            android:layout_height="75dp">

            <TextView
                android:text="Light Muted"
                android:textColor="@android:color/white"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/txtLightMutedColor"/>
        </FrameLayout>
        <FrameLayout
            android:id="@+id/mutedColor"
            android:layout_width="match_parent"
            android:layout_height="75dp">

            <TextView
                android:text="Muted"
                android:textColor="@android:color/white"
                android:layout_width="wrap_content"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/txtMutedColor"/>
        </FrameLayout>

        <FrameLayout
            android:id="@+id/darkMutedColor"
            android:layout_width="match_parent"
            android:layout_height="75dp">

            <TextView
                android:text="Dark Muted"
                android:textColor="@android:color/white"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/txtDarkMutedColor"/>
        </FrameLayout>

    </LinearLayout>

</LinearLayout>

Activity Code: PaletteActivity.java

package com.codeexa.com.firebaseexample;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.Toolbar;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;

public class PaletteActivity extends AppCompatActivity {
    private ImageView mImageView;
    private LinearLayout mContainer;
    private Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_palette);
        mToolbar = findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        mImageView = findViewById(R.id.imageView);
        mContainer = findViewById(R.id.container);
        extractColorProfile("https://codeexa.com/wp-content/uploads/2019/01/sunset.jpeg");
    }


    private void extractColorProfile(String imageUrl){

        GlideApp.with(this).asBitmap()
                .load(imageUrl)
                .into(new SimpleTarget<Bitmap>(){
                    @Override
                    public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                        mImageView.setImageBitmap(resource);
                        // Extract color
                        Palette.from(resource).generate(p -> {
                            int mutedLight = p.getLightMutedColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight2 = p.getMutedColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight3 = p.getDarkMutedColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight4 = p.getLightVibrantColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight5 = p.getVibrantColor(getResources().getColor(android.R.color.darker_gray));
                            int mutedLight6 = p.getDarkVibrantColor(getResources().getColor(android.R.color.darker_gray));

                            findViewById(R.id.lightVibrantColor).setBackgroundColor(mutedLight);
                            findViewById(R.id.vibrantColor).setBackgroundColor(mutedLight2);
                            findViewById(R.id.darkVibrantColor).setBackgroundColor(mutedLight3);
                            findViewById(R.id.lightMutedColor).setBackgroundColor(mutedLight4);
                            findViewById(R.id.mutedColor).setBackgroundColor(mutedLight5);
                            findViewById(R.id.darkMutedColor).setBackgroundColor(mutedLight6);
                            
                        });
                    }
                });
    }
}

 

Leave a Reply