Color dominant image background in Android application

Sourav Saha
3 min readMar 23, 2021

--

When you upload a story in instagram , have you ever noticed that the background of the image depends totally on the image you shared . That means , If you share a picture of a sky with clouds , the image background will have a color palette dominant of sky blue and grey cloud. Lets look at an image for example

Look at the above image. Depending on the image , the background has a gradient with colors that matches with the picture. If you try to upload different images , you will see the change of backgrounds.

In this article , I will try to explain a simple way of making such background in android application

First , Lets add the library we need to achieve this.

Add the below line to your app level build gradle.

implementation 'androidx.palette:palette:1.0.0'

Here is our activity_main layout xml file

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".MainActivity">

<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:scaleType="centerCrop"
android:layout_height="match_parent" />

<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/sample" />

</FrameLayout>

Here , the first imageview is for our dominant background and the later is our actual image for which we need the color dominant background. Basically , We will achieve the dominant color of the image we set in the second imageview (@ id/image) . Here “sample” is our image name which I saved in the drawable folder in android.

Here is my MainActivity.java file

package us.rent.dominantcolor;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
private ImageView backgroundImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.image);

backgroundImageView = findViewById(R.id.background);
Bitmap imageBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.sample);

imageView.setImageBitmap(imageBitmap);
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;

Bitmap backgroundDominantColorBitmap =PaletteUtils.getDominantGradient(imageBitmap,height,width);
backgroundImageView.setImageBitmap(backgroundDominantColorBitmap);

}
}

Lets see what we have done in this code.

  1. First , we type casted our two imageviews . One is our background and one is our main image.
  2. Then , we fetched the device width. This is because we need to fit our background image to the whole screen and we will set our main image on top of that.
  3. After that , we got the color dominant background image by a function called PaletteUtils.getDominantGradient(imageBitmap,height,width);
  4. Now , lets see the PaletterUtils class and the function getDominantGradient()
package us.rent.dominantcolor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;

import android.graphics.Shader;

import android.util.Log;

import androidx.palette.graphics.Palette;

import java.util.List;

public class PaletteUtils {

public static int getUpperSideDominantColor(Bitmap bitmap) {
Palette.Builder builder = new Palette.Builder(bitmap)
.setRegion(0, 0, bitmap.getWidth(), bitmap.getHeight() / 2);
int defaultValue = 0xFFFFFF;
Palette p = builder.generate();
return p.getDominantColor(defaultValue);
}

public static int getLowerSideDominantColor(Bitmap bitmap) {
int defaultValue = 0xFFFFFF;

Palette.Builder builder = new Palette.Builder(bitmap)
.setRegion(0, bitmap.getHeight() / 2, bitmap.getWidth(), bitmap.getHeight());
return builder.generate().getDominantColor(defaultValue);
}

public static Bitmap getDominantGradient(Bitmap bitmap, int height, int width) {
int topColor=0, bottomColor=0;
topColor = getUpperSideDominantColor(bitmap);
bottomColor = getLowerSideDominantColor(bitmap);
String topHex = Integer.toHexString(topColor);
topHex =topHex.trim();
topHex = '#'+topHex;

String bottomHex = Integer.toHexString(bottomColor);
bottomHex = bottomHex.trim();
bottomHex = '#'+bottomHex;

Log.e("color ",topHex);
Log.e("color " , bottomHex);
int[] colors = new int[]{Color.parseColor(topHex), Color.parseColor(bottomHex)};
//int[]colors = new int[]{ Color.GREEN,Color.BLACK};

Shader mShader = new LinearGradient(0, 0, width/2, height/2, colors,
null, Shader.TileMode.CLAMP);
Matrix m = new Matrix();
m.setRotate(90);
mShader.setLocalMatrix(m);
Paint paint=new Paint();
paint.setShader(mShader);
Bitmap resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawRect(0,0,width,height,paint);
//canvas.drawRect(0,0,640,1137,paint);
Matrix matrix = new Matrix();
canvas.drawBitmap(resultBitmap,matrix,paint);

return resultBitmap;
}
}

In the above code , We Created two gradients with dominant color of our image. This is because , an image might have a dominant color in the upper side and another color dominance at the lower side. Here we created two bitmaps with just plain bitmap with two colors and merged them in a single bitmap with gradient. And then we used the merged bitmap as our image background above.

That’s all folks . . Happy androiding!! :)

--

--

Sourav Saha
Sourav Saha

Written by Sourav Saha

Programming , Travel , Mobile app ,Family and Dogs . Well that almost defines me!!

No responses yet