Android Working with Palette - Androhub

Palette Banner

Android Working with Palette

With the release of Android Lollipop, several new support libraries have been created. One of the new libraries is for the Palette class. This new class makes it easy to extract prominent colors from bitmap images, which is useful if you want to style other view components to match colors from your image, such as a background for the image or a text color with suitable contrast. One way I like to use this is to color the ripple drawable behind the image. It is a subtle effect, but I think it is a nice improvement over the standard grey.

For example, you can use a palette to create a color-coordinated title card for a song based on its album cover or to adjust an app’s toolbar color when its background image changes.

Palette object gives you access to the colors in a Bitmap image while also providing six main color profiles from the bitmap to help inform your design choices.

Prerequisite:

Example

In this tutorial, we are going to learn how to Select Colors with the Palette API and using Picasso to load images.

VIDEO DEMO

1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.

2. Open res ⇒ values ⇒ strings.xml and add below string values. These are some strings that we are going to use in our project.

3. Before you can use Palette in your projects you need to add the following compile line to your Gradle dependencies block in your build.gradle file.

As i am using Picasso library also for loading image url and RecyclerView for Grid representation, so the build.gradle will change as per below:

4. Create activity_main.xml layout and place the below code. This layout will contain the displayed image and TextViews to display the extracted colors.

5. After creating layout xml let’s move to generating Palette process:

In order to generate the Palette object, there is a static from(Bitmap) method on the Palette class. This method returns a Palette.Builder object that you can use to tweak the generated Palette. Be sure that the Bitmap you supply to the from()method is neither null nor recycled, or it will throw an IllegalArgumentException.

Once you have the builder, you can use one of the generate methods to create thePalette object. One option is to use the no-argument generate() method like so.

Generate a Palette instance

Generate a Palette instance using Palette’s from(Bitmap bitmap) method to first create a Palette.Builder from a Bitmap. The builder can then generate the palette either synchronously or asynchronously.

Use synchronous palette generation if you want to create the palette on the same thread as the method being called. If you generate the palette asynchronously on a different thread, use the onGenerated() method to access the palette immediately after it has been created.

  • Synchronously Palette Generation

  • Asynchronously Palette Generation

Using the Palette

When a palette is generated, it tries to pick six swatches which match certain criteria:

Which one you choose depends on your use case. Vibrant and Dark Vibrant are the ones that developers will use mostly though.

Using a swatch

Each Swatch contains the following methods:

Customize your Palette

The Palette.Builder allows you to customize your palette by choosing how many colors are in the resulting palette, what area of your image the builder uses to generate the palette, and what colors are allowed in the palette. For example, you can filter out the color black or ensure that the builder only uses the top half of an image to generate your palette.

Fine-tune your palette’s size and colors with the following methods from the Palette.Builder class:

  • addFilter() : This method adds a filter that indicates what colors are allowed in the resulting palette. Pass in your own Palette.Filter and modify its isAllowed() method to determine which colors are filtered from the palette.
  • maximumColorCount() : This method sets the maximum number of colors in your palette. The default value is 16, and the optimal value depends on the source image. For landscapes, optimal values range from 8-16 while pictures with faces usually have values that fall between 24-32. The Palette.Builder takes longer to generate palettes with more colors.
  • setRegion() : This method indicates what area of the bitmap the builder uses when creating the palette. You can only use this method when generating the palette from a bitmap, and it does not affect the original image.
  • addTarget() : This method allows you to perform your own color matching by adding a Target color profile to the builder. If the default Targets are not sufficient, advanced developers can create their own Targets using a Target.Builder.

Custom color selection

But what if you do not like Palette’s color selections? In this case, you can grab all of the swatches which make up the Palette as so:

You can then iterate over them and choose whichever color you want.

The following code uses the methods to synchronously generate a palette, get its vibrant swatch, and change the colors of a toolbar to match the bitmap image.

 

Below are the snapshots with two different images displaying extracted Palette colors and also with changed toolbar background color and title color.

photo_palette

 

house_palette

6. Now open your MainActivity.java and place the below code. In this class we are using all the above steps that we learnt in above point.

7. As we will also work in RecyclerView and Picasso. So lets create new xml layout naming recycler_view_activity.xml and place the below code to it.

8. After creating recycler_view_activity layout, now create custom row layout for recycler view item naming recycler_view_custom_row.xml and place the below code to it. In this layout we are only taking ImageView and TextView to display the Palette colors.

9. Now create POJO class for RecyclerView custom layout naming RecyclerItemModel.java and place the below code to it.

10. Now create new activity class naming RecyclerView_Activity.java and place the below code to it. In this class we are taking some image urls and adding them to ArrayList.

11. Finally create adapter for RecyclerView naming RecyclerViewAdapter.java and place the below code to it.

Below are the process how Palette Generation work with Picasso or any other library:

The default code of Picasso to load images is:

The problem in above code is that we have no access to the loaded image. The library downloads the image, resize it and define sets it into the ImageView in a totally automated way. To allow us to handle the downloaded image and extract it’s colors, lets change some lines of code. Instead of loading the image into the ImageView, we will load it into a custom target. This way, we will have access to the bitmap, making easier to extract it’s colors.

Now we can handle the bitmap inside the method onBitmapLoaded. We can extract it’s colors and then set the bitmap as image source in our ImageView. But not that fast. Changing the target of image loading has another consequence: Picasso now has no dimensions to resize the image. When the loading target is an ImageView, Picasso can resize the bitmap with it’s dimensions. A custom target has no dimensions, so the bitmap we receive as parameter has the original size. For that reason, we have some more lines of code. We must call resize and centerCrop to reduce the image before processing it.

Finally we can extract images’s colors. We can create a new instance from Palette class using the method from, using our bitmap as parameter. A new color set will be generated with the method generate(). This process can take some time, so it will be executed in an asynchronous way, avoiding main thread blocks.

When the process finishes, we will have a palette with multiple combinations. After Palette generations we get all type of colors as we got in MainActivity.java use getTitleTextColor() to get text color and getRgb() for text background color. Don’t forget that the sets can be null, since an image may have no vibrant colors,

Below is a screenshot of what we got when we open RecyclerView_Activity.java.

grid_palette

12. Make sure you give INTERNET permission in AndroidManifest.xml file to load image urls.

13. Finally you are all done. Now you can also use the Palette in your app.

Thanks. :)

 

Post comment

Your email address will not be published. Required fields are marked *