Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to extract Image Color with Palette in Android

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article Xiaobian for you to introduce in detail "Android how to use Palette to extract picture color", the content is detailed, the steps are clear, the details are handled properly, I hope this "Android how to extract picture color using Palette" article can help you solve your doubts, following the editor's ideas slowly in depth, together to learn new knowledge.

Preface

Palette, the color palette, has been released a long time ago, and Jetpack also includes this function. If you want to use this feature, you need to rely on the library.

Implementation 'androidx.palette:palette:1.0.0' creates a Palette

Creating a Palette is actually very simple, as follows

Var builder = Palette.from (bitmap) var palette = builder.generate ()

In this way, we create a Pallete object through a Bitmap.

Note: it is OK to use Palette.generate (bitmap) directly, but this method is no longer recommended, and it is still used in many old articles online. It is recommended to use Palette.Builder as an approach.

The function generate () is synchronous. Of course, considering that image processing may be time-consuming, Android also provides asynchronous functions.

Public AsyncTask generate (@ NonNull final PaletteAsyncListener listener) {

Obtain the Palette instance through a PaletteAsyncListener. This API is as follows:

Public interface PaletteAsyncListener {/ * * Called when the {@ link Palette} has been generated. {@ code null} will be passed when an * error occurred during generation. * / void onGenerated (@ Nullable Palette palette);} extract color

With the Palette instance, you can obtain the colors in the image through the corresponding function of the Palette object, and there is more than one color, listed below:

GetDominantColor: get the dominant tone in a picture

GetMutedColor: get the soft colors in the picture

GetDarkMutedColor: get the soft dark colors in the picture

GetLightMutedColor: get the soft bright colors in the picture

GetVibrantColor: get the vibrant colors in the picture

GetDarkVibrantColor: get the vibrant dark colors in the picture

GetLightVibrantColor: get the vibrant bright colors in the picture

These functions all need to provide a default color, which is used if the color Swatch is not valid. It's not intuitive to say that. Let's test it. The code is as follows:

Var bitmap = BitmapFactory.decodeResource (resources, R.mipmap.a) var builder = Palette.from (bitmap) var palette = builder.generate () color0.setBackgroundColor (palette.getDominantColor (Color.WHITE)) color1.setBackgroundColor (palette.getMutedColor (Color.WHITE)) color2.setBackgroundColor (palette.getDarkMutedColor (Color.WHITE) color3.setBackgroundColor (palette.getLightMutedColor (Color.WHITE)) color4.setBackgroundColor (palette.getVibrantColor (Color.WHITE)) color5.setBackgroundColor (palette.getDarkVibrantColor (Color.WHITE) color6.setBackgroundColor (palette.getLightVibrantColor (Color.WHITE))

The results are as follows:

In this way, the difference of each color is clear at a glance. In addition to the above function, you can also use the getColorForTarget function, as follows:

@ ColorIntpublic int getColorForTarget (@ NonNull final Target target, @ ColorInt final int defaultColor) {

This function requires a Target, which provides six static fields, as follows:

/ * * A target which has the characteristics of a vibrant color which is light in luminance.*/public static final Target LIGHT_VIBRANT;/** * A target which has the characteristics of a vibrant color which is neither light or dark. * / public static final Target VIBRANT;/** * A target which has the characteristics of a vibrant color which is dark in luminance. * / public static final Target DARK_VIBRANT;/** * A target which has the characteristics of a muted color which is light in luminance. * / public static final Target LIGHT_MUTED;/** * A target which has the characteristics of a muted color which is neither light or dark. * / public static final Target MUTED;/** * A target which has the characteristics of a muted color which is dark in luminance. * / public static final Target DARK_MUTED

In fact, it corresponds to the six colors above in addition to the main tone.

Automatic adaptation of text color

As you can see in the above running results, the text on each color is clearly displayed, and they are not the same color. In fact, this is also the function provided by Palette.

Through the following function, we can get the Swatch objects corresponding to various tones:

GetDominantSwatch

GetMutedSwatch

GetDarkMutedSwatch

GetLightMutedSwatch

GetVibrantSwatch

GetDarkVibrantSwatch

GetLightVibrantSwatch

Note: as above, it can also be obtained through getSwatchForTarget (@ NonNull final Target target)

The Swatch class provides the following functions:

GetPopulation (): the number of pixels in the sample

GetRgb (): the RBG value of the color

GetHsl (): HSL value of the color

GetBodyTextColor (): can all match the color value of the body text of this Swatch

GetTitleTextColor (): can all match the color value of the title text of this Swatch

So we can easily get the title and body text color that can be very realistic on this color through getBodyTextColor () and getTitleTextColor (). So the above test code is complete as follows:

Var bitmap = BitmapFactory.decodeResource (resources R.mipmap.a) var builder = Palette.from (bitmap) var palette = builder.generate () color0.setBackgroundColor (palette.getDominantColor (Color.WHITE)) color0.setTextColor (palette.dominantSwatch?.bodyTextColor?: Color.WHITE) color1.setBackgroundColor (palette.getMutedColor (Color.WHITE)) color1.setTextColor (palette.mutedSwatch?.bodyTextColor?: Color.WHITE) color2.setBackgroundColor (palette.getDarkMutedColor (Color.WHITE)) color2.setTextColor (palette.darkMutedSwatch?.bodyTextColor?: Color.WHITE) color3.setBackgroundColor (palette.getLightMutedColor (Color. WHITE)) color3.setTextColor (palette.lightMutedSwatch?.bodyTextColor?: Color.WHITE) color4.setBackgroundColor (palette.getVibrantColor (Color.WHITE)) color4.setTextColor (palette.vibrantSwatch?.bodyTextColor?: Color.WHITE) color5.setBackgroundColor (palette.getDarkVibrantColor (Color.WHITE)) color5.setTextColor (palette.darkVibrantSwatch?.bodyTextColor?: Color.WHITE) color6.setBackgroundColor (palette.getLightVibrantColor (Color.WHITE)) color6.setTextColor (palette.lightVibrantSwatch?.bodyTextColor?: Color.WHITE)

In this way, the text on each color can be clearly displayed.

So what is the difference between the color of the title and the main text, and how do they get it? Let's look at the source code:

/ * Returns an appropriate color to use for any 'title' text which is displayed over this * {@ link Swatch}' s color. This color is guaranteed to have sufficient contrast. * / @ ColorIntpublic int getTitleTextColor () {ensureTextColorsGenerated (); return mTitleTextColor;} / * * Returns an appropriate color to use for any 'body' text which is displayed over this * {@ link Swatch}' s color. This color is guaranteed to have sufficient contrast. * / @ ColorIntpublic int getBodyTextColor () {ensureTextColorsGenerated (); return mBodyTextColor;}

You can see that ensureTextColorsGenerated () is executed first, and its source code is as follows:

Private void ensureTextColorsGenerated () {if (! mGeneratedTextColors) {/ / First check white, as most colors will be dark final int lightBodyAlpha = ColorUtils.calculateMinimumAlpha (Color.WHITE, mRgb, MIN_CONTRAST_BODY_TEXT); final int lightTitleAlpha = ColorUtils.calculateMinimumAlpha (Color.WHITE, mRgb, MIN_CONTRAST_TITLE_TEXT) If (lightBodyAlpha! =-1 & & lightTitleAlpha! =-1) {/ / If we found valid light values, use them and return mBodyTextColor = ColorUtils.setAlphaComponent (Color.WHITE, lightBodyAlpha); mTitleTextColor = ColorUtils.setAlphaComponent (Color.WHITE, lightTitleAlpha); mGeneratedTextColors = true; return } final int darkBodyAlpha = ColorUtils.calculateMinimumAlpha (Color.BLACK, mRgb, MIN_CONTRAST_BODY_TEXT); final int darkTitleAlpha = ColorUtils.calculateMinimumAlpha (Color.BLACK, mRgb, MIN_CONTRAST_TITLE_TEXT) If (darkBodyAlpha! =-1 & & darkTitleAlpha! =-1) {/ / If we found valid dark values, use them and return mBodyTextColor = ColorUtils.setAlphaComponent (Color.BLACK, darkBodyAlpha); mTitleTextColor = ColorUtils.setAlphaComponent (Color.BLACK, darkTitleAlpha); mGeneratedTextColors = true; return } / If we reach here then we can not find title and body values which use the same / / lightness, we need to use mismatched values mBodyTextColor = lightBodyAlpha! =-1? ColorUtils.setAlphaComponent (Color.WHITE, lightBodyAlpha): ColorUtils.setAlphaComponent (Color.BLACK, darkBodyAlpha); mTitleTextColor = lightTitleAlpha! =-1? ColorUtils.setAlphaComponent (Color.WHITE, lightTitleAlpha): ColorUtils.setAlphaComponent (Color.BLACK, darkTitleAlpha); mGeneratedTextColors = true;}}

As you can see from the code, the two text colors are actually either white or black, but the transparency Alpha is different.

There is a key function, ColorUtils.calculateMinimumAlpha ():

Public static int calculateMinimumAlpha (@ ColorInt int foreground, @ ColorInt int background, float minContrastRatio) {if (Color.alpha (background)! = 255) {throw new IllegalArgumentException ("background can not be translucent: #" + Integer.toHexString (background));} / / First lets check that a fully opaque foreground has sufficient contrast int testForeground = setAlphaComponent (foreground, 255); double testRatio = calculateContrast (testForeground, background) If (testRatio < minContrastRatio) {/ / Fully opaque foreground does not have sufficient contrast, return error return-1;} / / Binary search to find a value with the minimum value which provides sufficient contrast int numIterations = 0; int minAlpha = 0; int maxAlpha = 255; while (numIterations MIN_ALPHA_SEARCH_PRECISION) {final int testAlpha = (minAlpha + maxAlpha) / 2; testForeground = setAlphaComponent (foreground, testAlpha) TestRatio = calculateContrast (testForeground, background); if (testRatio < minContrastRatio) {minAlpha = testAlpha;} else {maxAlpha = testAlpha;} numIterations++;} / / Conservatively return the max of the range of possible alphas, which is known to pass. Return maxAlpha;}

It calculates the most appropriate Alpha for the foreground color based on the background color and foreground color. During this period, if it is less than minContrastRatio,-1 is returned, indicating that the foreground color is not appropriate. The difference between the title and the main text is that the minContrastRatio is different.

Back to the ensureTextColorsGenerated code, you can see that the Alpha of the white foreground color is calculated according to the current hue, and if neither of the two Alpha is-1, the corresponding color is returned; otherwise, the Alpha of the black foreground color is calculated, if neither is-1, the corresponding color is returned; otherwise, the title and the body text are white and the other is black, and the corresponding color is returned.

More Featur

Above, when we create Palette, we first get a Palette.Builder object through Palette.from (bitmap). Through this builder, we can achieve more functions, such as:

AddFilter: add a filter

SetRegion: sets the extraction area on the picture

MaximumColorCount: the maximum number of colors for the palette

Wait

Read this, the "Android how to use Palette to extract picture color" article has been introduced, want to master the knowledge of this article also need to practice and use in order to understand, if you want to know more related articles, welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report