在android中具有色调时查找颜色名称

在android中具有色调时查找颜色名称,android,bitmap,rgb,pixel,hsv,Android,Bitmap,Rgb,Pixel,Hsv,我只关心12种颜色: red: RGB: 255, 0, 0 pink: RGB: 255, 192, 203 violet: RGB: 36, 10, 64 blue: RGB: 0, 0, 255 green: RGB: 0, 255, 0 yellow: RGB: 255, 255, 0 orange: RGB: 255, 104, 31 white: RGB: 255, 255, 255 black: RGB: 0, 0, 0 gray: RGB: 128, 128, 128 tea:

我只关心12种颜色:

red: RGB: 255, 0, 0
pink: RGB: 255, 192, 203
violet: RGB: 36, 10, 64
blue: RGB: 0, 0, 255
green: RGB: 0, 255, 0
yellow: RGB: 255, 255, 0
orange: RGB: 255, 104, 31
white: RGB: 255, 255, 255
black: RGB: 0, 0, 0
gray: RGB: 128, 128, 128
tea: RGB: 193, 186, 176
cream: RGB: 255, 253, 208
当我读取位图的像素时,我可以得到色调值:

int picw = mBitmap.getWidth();
    int pich = mBitmap.getHeight();
    int[] pix = new int[picw * pich];
    float[] HSV = new float[3];

    // get pixel array from source
    mBitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);

    int index = 0;
    // iteration through pixels
    for(int y = 0; y < pich; ++y) {
        for(int x = 0; x < picw; ++x) {
            // get current index in 2D-matrix
            index = y * picw + x;               
            // convert to HSV
            Color.colorToHSV(pix[index], HSV);
            // increase Saturation level
            //HSV[0] = Hue
            Log.i(getCallingPackage(), String.valueOf(HSV[0]));
        }
    }
intpicw=mBitmap.getWidth();
int pich=mBitmap.getHeight();
int[]pix=新的int[picw*pich];
浮动[]HSV=新浮动[3];
//从源获取像素阵列
mBitmap.getPixels(像素,0,像素,0,0,像素,像素);
int指数=0;
//像素迭代
对于(int y=0;y
现在我想知道这个像素是什么颜色的(只有上面12种颜色)

我使用HSV来查看颜色范围。当我有一种颜色不在这个列表中时,我想在我的列表中将它命名为相似的颜色 我怎么做


非常感谢您

,因为您已经有了int中的像素颜色值。 可以使用以下方法提取RGB值

int green = Color.green(pix[i]);
int red   = Color.red(pix[i]);
int blue  = Color.blue(pix[i]);

然后与您拥有的RGB值进行比较,因为您已经拥有int中的像素颜色值。 可以使用以下方法提取RGB值

int green = Color.green(pix[i]);
int red   = Color.red(pix[i]);
int blue  = Color.blue(pix[i]);

然后与您的RGB值进行比较

根据您的评论,您基本上是在尝试将位图的全色调色板减少到您指定的12。显然,对于位图中的每个像素,应该从这12个像素中选择“最佳匹配”

我仍然不明白为什么需要HSV值,因为它只是RGB组件的一种不同表示形式,实际上并没有改变问题或解决方案

找到任何RGB颜色的最佳匹配的简单方法如下所示

首先建立一个包含你想要匹配的颜色的列表。我用了一张地图,因为你提到你(也)想知道颜色的名称,而不仅仅是RGB值

Map<String, Integer> mColors = new HashMap<String, Integer>();
mColors.put("red", Color.rgb(255, 0, 0));
mColors.put("pink", Color.rgb(255, 192, 203));
mColors.put("voilet", Color.rgb(36, 10, 64));
mColors.put("blue", Color.rgb(0, 0, 255));
mColors.put("green", Color.rgb(0, 255, 0));
mColors.put("yellow", Color.rgb(255, 255, 0));
mColors.put("orange", Color.rgb(255, 104, 31));
mColors.put("white", Color.rgb(255, 255, 255));
mColors.put("black", Color.rgb(0, 0, 0));
mColors.put("gray", Color.rgb(128, 128, 128));
mColors.put("tea", Color.rgb(193, 186, 176));
mColors.put("cream", Color.rgb(255, 253, 208));
括号中的第一个数字是颜色常数的实际int值,第二个是找到的最佳匹配的int值,名称就在前面

Color.MAGENTA
的结果也说明了为什么不应该直接比较颜色的int值。实际的int值是
-65281
,这与
Color.RED
(-65536)的值非常接近。然而,基于不同成分的最佳匹配是“粉色”,其值为-16181。显然,知道颜色定义为4个字节是完全有意义的:

颜色表示为压缩整数,由4个字节组成:alpha、red、, 绿色,蓝色。(…)组件存储如下(alpha 0){ //这种颜色的名字 字符串currentColorName=colorNameIterator.next(); //这种颜色的int值 int color=mColors.get(currentColorName); //获取此颜色的HSV值 float[]colorHsv=新浮点[3]; Color.colorToHSV(Color,colorToHSV); //计算表示此匹配有多好的绝对差值之和 浮点差=Math.abs(pixelColorHsv[0]-colorHsv[0])+Math.abs(pixelColorHsv[1]-colorHsv[1])+Math.abs(pixelColorHsv[2]-colorHsv[2]); //一个较小的差异意味着一个更好的匹配,所以存储它 如果(当前差异>差异){ 电流差=差; closestColorName=currentColorName; } } 返回closestColorName; }
根据您的评论,您似乎基本上是在尝试将位图的全色调色板减少到您指定的12种颜色。显然,对于位图中的每个像素,应该从这12个像素中选择“最佳匹配”

我仍然不明白为什么需要HSV值,因为它只是RGB组件的一种不同表示形式,实际上并没有改变问题或解决方案

找到任何RGB颜色的最佳匹配的简单方法如下所示

首先建立一个包含你想要匹配的颜色的列表。我用了一张地图,因为你提到你(也)想知道颜色的名称,而不仅仅是RGB值

Map<String, Integer> mColors = new HashMap<String, Integer>();
mColors.put("red", Color.rgb(255, 0, 0));
mColors.put("pink", Color.rgb(255, 192, 203));
mColors.put("voilet", Color.rgb(36, 10, 64));
mColors.put("blue", Color.rgb(0, 0, 255));
mColors.put("green", Color.rgb(0, 255, 0));
mColors.put("yellow", Color.rgb(255, 255, 0));
mColors.put("orange", Color.rgb(255, 104, 31));
mColors.put("white", Color.rgb(255, 255, 255));
mColors.put("black", Color.rgb(0, 0, 0));
mColors.put("gray", Color.rgb(128, 128, 128));
mColors.put("tea", Color.rgb(193, 186, 176));
mColors.put("cream", Color.rgb(255, 253, 208));
括号中的第一个数字是颜色常数的实际int值,第二个是找到的最佳匹配的int值,名称就在前面

Color.MAGENTA
的结果也说明了为什么不应该直接比较颜色的int值。实际的int值是
-65281
,这与
Color.RED
(-65536)的值非常接近。然而,基于不同成分的最佳匹配是“粉色”,其值为-16181。显然,知道颜色定义为4个字节是完全有意义的:

颜色表示为压缩整数,由4个字节组成:alpha、red、, 绿色,蓝色。(…)组件存储如下(alpha 0){ //这种颜色的名字 字符串currentColorName=colorNameIterator.next(); //这种颜色的int值 int color=mColors.get(currentColorName); //获取此颜色的HSV值 float[]colorHsv=新浮点[3]; Color.colorToHSV(Color,colorToHSV); //计算表示此匹配有多好的绝对差值之和 浮点差=Math.abs(pixelColorHsv[0]-colorHsv[0])+Math.abs(pixelColorHsv[1]-colorHsv[1])+Math.abs(pixelColorHsv[2]-colorHsv[2]); //一个较小的差异意味着一个更好的匹配,所以存储它 如果(当前差异>差异){ 电流差=差; closestColorName=currentColorName; } } 返回closestColorName; } 当我有一种颜色
private String getBestMatchingHsvColor(int pixelColor) {
    // largest difference is 360(H), 1(S), 1(V)
    float currentDifference = 360 + 1 + 1;
    // name of the best matching colour
    String closestColorName = null;
    // get HSV values for the pixel's colour
    float[] pixelColorHsv = new float[3];
    Color.colorToHSV(pixelColor, pixelColorHsv);

    Iterator<String> colorNameIterator = mColors.keySet().iterator();
    // continue iterating if the map contains a next colour and the difference is greater than zero.
    // a difference of zero means we've found an exact match, so there's not point in iterating further.
    while (colorNameIterator.hasNext() && currentDifference > 0) {
        // this colour's name
        String currentColorName = colorNameIterator.next();
        // this colour's int value
        int color = mColors.get(currentColorName);
        // get HSV values for this colour
        float[] colorHsv = new float[3];
        Color.colorToHSV(color, colorHsv);
        // calculate sum of absolute differences that indicates how good this match is 
        float difference = Math.abs(pixelColorHsv[0] - colorHsv[0]) + Math.abs(pixelColorHsv[1] - colorHsv[1]) + Math.abs(pixelColorHsv[2] - colorHsv[2]);
        // a smaller difference means a better match, so store it
        if (currentDifference > difference) {
            currentDifference = difference;
            closestColorName = currentColorName;
        }
    }
    return closestColorName;
}