我有以下图像:
我有以下方法从图像的位图返回调色板颜色:
public static int getPredominantColorFromPokemon(String pokemonId, Context context) {
int pokemonImage = PokemonUtils.getPokemonSugimoriImageById(pokemonId, context);
if (pokemonImage == 0) {
return Color.WHITE;
}
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), pokemonImage);
Palette palette = Palette.from(bitmap).generate();
int colorPalette1 = palette.getLightVibrantColor(Color.WHITE);
int colorPalette2 = colorPalette1 == -1 ? palette.getVibrantColor(Color.WHITE) : colorPalette1;//Fallback
int colorPalette3 = colorPalette2 == -1 ? palette.getLightMutedColor(Color.WHITE) : colorPalette2; //Fallback
int colorPalette4 = colorPalette3 == -1 ? palette.getDominantColor(Color.WHITE) : colorPalette3;//Fallback
return colorPalette4;
}
这3幅图像的结果颜色如下:
然而,这不是我想要的,我想要的输出是这样的:
第一张和第二张图像的结果是好的,背景是一种绿色,因为主要颜色是绿色,但是在第三张图像(金星号)的情况下不是,因为结果是一种粉色/紫色,我希望调色板检测绿色。 我如何修改我的方法以检测主要颜色?
颜色是非常主观的,并不总是一个明确的决定哪种颜色是主导的。 关键因素是发光,历史记录。 显然,谷歌的实现认为粉色比蓝色更重要。 这甚至是可以理解的,因为红/橙/黄是人眼感知更重要的信号颜色(与它们在图像中的数量无关)。
想象一个灰色的大矩形,里面有一个霓虹灯粉红色的小圆圈。 你可能会觉得霓虹灯粉色是主导色,而不是灰色。 即使这样,灰的量也更大。
所以简而言之:如果你想使用调色板API,你必须处理它给你的结果。
但是由于调色板API提供了几种提取的颜色,您可以将它们的色调与图像的历史记录图进行比较,并相应地选择您喜欢的调色板颜色。
下面是一个例子,说明如何将一种颜色从RGB转换为HSV,然后再转换回来。
int color = Color.rgb(206, 43, 55);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
System.out.println(red + ", " + green + ", " + blue);
//prints: 206, 43, 55 (as expected)
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];
int outputColor = Color.HSVToColor(hsv);
red = Color.red(outputColor);
green = Color.green(outputColor);
blue = Color.blue(outputColor);
System.out.println(red + ", " + green + ", " + blue);
首先,我尝试只使用HSV,因为创建直方图非常慢,因为您基本上必须迭代图像的每个像素,并将其颜色累积到列表中。 三次。 红色,绿色和蓝色。
这是你找不到“完美解决方案”的地方。 相反,您可能需要在可维护性代码,速度和应用程序需求之间权衡取舍。
祝你好运!