Here is a way to get the dominant (NOT average) colors of an image using Material color utilities library 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 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 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 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:
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:
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 (like colorScheme.primary
used in the above code snippets).