Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 710 Vote(s) - 3.45 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How can I get the average color of an image?

#1
I want to be able to take an image and find out what is its average color, meaning if the image is half black and half white, I would get something in-between... some shade of gray. It could be the most frequent single color or median. Any average will do.

How can I do this in Android?
Reply

#2
Use the `Bitmap.getPixels()` method to get the color values. Then to calculate the average you have to decide what you mean by that. In a grayscale image it is simple, but with colors there are no such thing as an average. You can separate into components (for example RGBA), and take the average of each component. An alternative is to search for the most commonly used color, and there are several other options I'm sure. Play with it :)
Reply

#3
Bitmap bitmap = someFunctionReturningABitmap();
long redBucket = 0;
long greenBucket = 0;
long blueBucket = 0;
long pixelCount = 0;

for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
Color c = bitmap.getPixel(x, y);

pixelCount++;
redBucket += Color.red©;
greenBucket += Color.green©;
blueBucket += Color.blue©;
// does alpha matter?
}
}

Color averageColor = Color.rgb(redBucket / pixelCount,
greenBucket / pixelCount,
blueBucket / pixelCount);
Reply

#4
Building off Dan O's solution, here's a method that automatically takes into account the alpha channel and makes the optimization/ tradeoff of `getPixels` vs `getPixel`.

The cost is memory but the benefit is performance, invocation of a virtual method in a loop that could possibly be run several million times [i.e. an 8MP image has 3,456x2,304 = 7,962,624 pixels]). I've even taken things one step further by removing the looped `android.graphics.Color` method calls.

public static int getDominantColor(Bitmap bitmap) {
if (null == bitmap) return Color.TRANSPARENT;

int redBucket = 0;
int greenBucket = 0;
int blueBucket = 0;
int alphaBucket = 0;

boolean hasAlpha = bitmap.hasAlpha();
int pixelCount = bitmap.getWidth() * bitmap.getHeight();
int[] pixels = new int[pixelCount];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());

for (int y = 0, h = bitmap.getHeight(); y < h; y++)
{
for (int x = 0, w = bitmap.getWidth(); x < w; x++)
{
int color = pixels[x + y * w]; // x + y * width
redBucket += (color >> 16) & 0xFF; // Color.red
greenBucket += (color >> 8) & 0xFF; // Color.greed
blueBucket += (color & 0xFF); // Color.blue
if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
}
}

return Color.argb(
(hasAlpha) ? (alphaBucket / pixelCount) : 255,
redBucket / pixelCount,
greenBucket / pixelCount,
blueBucket / pixelCount);
}
Reply

#5
There is also a library that can do this for you.

[To see links please register here]

Reply

#6
You can use `Palete` class from [AndroidX][1], or from the the [v7-support library][2].

It provides additional methods to extract colours from a Bitmap, such as getting:

- Most Dominant color
- Vibrant colors
- Muted color
- much more


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#7
I think you will have to do that yourself.

Just create an int array with all the colors:

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
int intArray[] = new int[bmp.getWidth()*bmp.getHeight()];
bmp.getPixels(intArray, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());

Then you can get the color with intArray[0], the value could be 0xFFFF0000 for red (last 6 numbers are the RGB color value).

Here is another easy solution:

- Get you full-size image in a bitmap.

- Create a scaled bitmap of 1*1px.

- Get this bitmap color.

Reply

#8
Expanding on the second idea from [Stephane Mathis' answer][1], you can resize the image to 1x1 and get the color of that image:

```java
Bitmap originalBitmap = /*your original image*/;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, 1, 1, false); //Resize the bitmap to 1x1
@ColorInt int averageColor = scaledBitmap.getPixel(0, 0); //Get the color of the only pixel of the 1x1 bitmap
```

If your original image is not a `Bitmap` object, you can convert it to a `Bitmap` using one of the methods described [here][2].


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#9
Here is a way to get the **dominant** (NOT average) colors of an image using [Material color utilities library](

[To see links please register here]

) which is currently available for Java/Kotlin, C++, Dart, TypeScript.

The colors may not necessarily be the most recurring colors; the library extracts dominant colors appropriate for [Material 3 design system](

[To see links please register here]

) and appropriate to be used on light or dark themes in apps.

The library is primarily used on apps for Android 12 and above and also on the [Material Design website][1] itself but I tested it for myself and got good results.

To use the library, copy-paste the code on the [Material color utilities repository](

[To see links please register here]

) for your desired language to your project and then you can extract dominant colors and color schemes.

Here is an example for Java and Kotlin:

Java:

```java
var MAX_DESIRED_COLOR_COUNT = 128;
var file = new File("my-image.jpg");
var image = ImageIO.read(file);
var pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());
var colorFrequency = QuantizerCelebi.quantize(pixels, MAX_DESIRED_COLOR_COUNT);
var decentColors = Score.score(colorFrequency);
var desiredColor = decentColors.get(0);
// You can take the desiredColor or any other decentColors and forget the rest of code below


// Could also use Scheme.dark(desiredColor); to get colors suitable for dark themes
var colorScheme = Scheme.light(desiredColor);
System.out.println("Decent colors: " + decentColors);
System.out.println("Primary color (light theme): " + colorScheme.getPrimary());
```

Kotlin:

```kotlin
val MAX_DESIRED_COLOR_COUNT = 128
val file = File("my-image.jpg")
val image = ImageIO.read(file)
val pixels = image.getRGB(0, 0, image.width, image.height, null, 0, image.width)
val colorFrequency = QuantizerCelebi.quantize(pixels, MAX_DESIRED_COLOR_COUNT)
val decentColors = Score.score(colorFrequency)
val desiredColor = decentColors.first()
// You can take the desiredColor or any other decentColors and forget the rest of code below


// Could also use Scheme.dark(desiredColor) to get colors suitable for dark themes
val colorScheme = Scheme.light(desiredColor)
println("Decent colors: ${decentColors.joinToString { it.toHexString() }}")
println("Primary color (light theme): ${colorScheme.primary.toHexString()}")

fun Int.toHexString() = "#%06X".format(this and 0xFFFFFF)
```

Learn more about [Material Design color system and color roles here](

[To see links please register here]

) (like `colorScheme.primary` used in the above code snippets).

[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through