提问者:小点点

Android调色板不选择主要颜色


我有以下图像:

我有以下方法从图像的位图返回调色板颜色:

 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幅图像的结果颜色如下:

然而,这不是我想要的,我想要的输出是这样的:

第一张和第二张图像的结果是好的,背景是一种绿色,因为主要颜色是绿色,但是在第三张图像(金星号)的情况下不是,因为结果是一种粉色/紫色,我希望调色板检测绿色。 我如何修改我的方法以检测主要颜色?


共1个答案

匿名用户

颜色是非常主观的,并不总是一个明确的决定哪种颜色是主导的。 关键因素是发光,历史记录。 显然,谷歌的实现认为粉色比蓝色更重要。 这甚至是可以理解的,因为红/橙/黄是人眼感知更重要的信号颜色(与它们在图像中的数量无关)。

想象一个灰色的大矩形,里面有一个霓虹灯粉红色的小圆圈。 你可能会觉得霓虹灯粉色是主导色,而不是灰色。 即使这样,灰的量也更大。

所以简而言之:如果你想使用调色板API,你必须处理它给你的结果。

但是由于调色板API提供了几种提取的颜色,您可以将它们的色调与图像的历史记录图进行比较,并相应地选择您喜欢的调色板颜色。

下面是一个例子,说明如何将一种颜色从RGB转换为HSV,然后再转换回来。

  • h=色调=您正在处理的颜色的基本类型(红色,绿色,橙色等)
  • S=饱和度(色调的强度。重红色或浅红色)
  • v=值(色调的亮度。从完全暗到完全亮)
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,因为创建直方图非常慢,因为您基本上必须迭代图像的每个像素,并将其颜色累积到列表中。 三次。 红色,绿色和蓝色。

这是你找不到“完美解决方案”的地方。 相反,您可能需要在可维护性代码,速度和应用程序需求之间权衡取舍。

祝你好运!