Color dominant image background in Android application
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.
- First , we type casted our two imageviews . One is our background and one is our main image.
- 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.
- After that , we got the color dominant background image by a function called PaletteUtils.getDominantGradient(imageBitmap,height,width);
- 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!! :)