Converter valores RGB para o nome da cor

Como posso converter uma cor no formato RGB em um nome de cor?

Exemplos:

  • (0, 0, 255) -> “azul”
  • (255, 0, 0) -> “vermelho”
  • (128, 128, 128) -> “cinza”

  1. Preencher uma lista de colors “conhecidas”.
  2. Para cada cálculo de colors conhecido:

    rgbDistance = Math.abs(myColor.getRed() - colorI.getRed() + Math.abs(myColor.getGreen() - colorI.getGreen()) + Math.abs(myColor.getBlue() - colorI.getBlue()) 
  3. Retorna o nome de colorI para o qual rgbDistance era menor.

Aqui está um código de exemplo de trabalho que faz isso. Converte um valor rgb / hexadecimal / awt no nome da cor mais próxima.

 import java.awt.Color; import java.util.ArrayList; /** * Java Code to get a color name from rgb/hex value/awt color * * The part of looking up a color name from the rgb values is edited from * https://gist.github.com/nightlark/6482130#file-gistfile1-java (that has some errors) by Ryan Mast (nightlark) * * @author Xiaoxiao Li * */ public class ColorUtils { /** * Initialize the color list that we have. */ private ArrayList initColorList() { ArrayList colorList = new ArrayList(); colorList.add(new ColorName("AliceBlue", 0xF0, 0xF8, 0xFF)); colorList.add(new ColorName("AntiqueWhite", 0xFA, 0xEB, 0xD7)); colorList.add(new ColorName("Aqua", 0x00, 0xFF, 0xFF)); colorList.add(new ColorName("Aquamarine", 0x7F, 0xFF, 0xD4)); colorList.add(new ColorName("Azure", 0xF0, 0xFF, 0xFF)); colorList.add(new ColorName("Beige", 0xF5, 0xF5, 0xDC)); colorList.add(new ColorName("Bisque", 0xFF, 0xE4, 0xC4)); colorList.add(new ColorName("Black", 0x00, 0x00, 0x00)); colorList.add(new ColorName("BlanchedAlmond", 0xFF, 0xEB, 0xCD)); colorList.add(new ColorName("Blue", 0x00, 0x00, 0xFF)); colorList.add(new ColorName("BlueViolet", 0x8A, 0x2B, 0xE2)); colorList.add(new ColorName("Brown", 0xA5, 0x2A, 0x2A)); colorList.add(new ColorName("BurlyWood", 0xDE, 0xB8, 0x87)); colorList.add(new ColorName("CadetBlue", 0x5F, 0x9E, 0xA0)); colorList.add(new ColorName("Chartreuse", 0x7F, 0xFF, 0x00)); colorList.add(new ColorName("Chocolate", 0xD2, 0x69, 0x1E)); colorList.add(new ColorName("Coral", 0xFF, 0x7F, 0x50)); colorList.add(new ColorName("CornflowerBlue", 0x64, 0x95, 0xED)); colorList.add(new ColorName("Cornsilk", 0xFF, 0xF8, 0xDC)); colorList.add(new ColorName("Crimson", 0xDC, 0x14, 0x3C)); colorList.add(new ColorName("Cyan", 0x00, 0xFF, 0xFF)); colorList.add(new ColorName("DarkBlue", 0x00, 0x00, 0x8B)); colorList.add(new ColorName("DarkCyan", 0x00, 0x8B, 0x8B)); colorList.add(new ColorName("DarkGoldenRod", 0xB8, 0x86, 0x0B)); colorList.add(new ColorName("DarkGray", 0xA9, 0xA9, 0xA9)); colorList.add(new ColorName("DarkGreen", 0x00, 0x64, 0x00)); colorList.add(new ColorName("DarkKhaki", 0xBD, 0xB7, 0x6B)); colorList.add(new ColorName("DarkMagenta", 0x8B, 0x00, 0x8B)); colorList.add(new ColorName("DarkOliveGreen", 0x55, 0x6B, 0x2F)); colorList.add(new ColorName("DarkOrange", 0xFF, 0x8C, 0x00)); colorList.add(new ColorName("DarkOrchid", 0x99, 0x32, 0xCC)); colorList.add(new ColorName("DarkRed", 0x8B, 0x00, 0x00)); colorList.add(new ColorName("DarkSalmon", 0xE9, 0x96, 0x7A)); colorList.add(new ColorName("DarkSeaGreen", 0x8F, 0xBC, 0x8F)); colorList.add(new ColorName("DarkSlateBlue", 0x48, 0x3D, 0x8B)); colorList.add(new ColorName("DarkSlateGray", 0x2F, 0x4F, 0x4F)); colorList.add(new ColorName("DarkTurquoise", 0x00, 0xCE, 0xD1)); colorList.add(new ColorName("DarkViolet", 0x94, 0x00, 0xD3)); colorList.add(new ColorName("DeepPink", 0xFF, 0x14, 0x93)); colorList.add(new ColorName("DeepSkyBlue", 0x00, 0xBF, 0xFF)); colorList.add(new ColorName("DimGray", 0x69, 0x69, 0x69)); colorList.add(new ColorName("DodgerBlue", 0x1E, 0x90, 0xFF)); colorList.add(new ColorName("FireBrick", 0xB2, 0x22, 0x22)); colorList.add(new ColorName("FloralWhite", 0xFF, 0xFA, 0xF0)); colorList.add(new ColorName("ForestGreen", 0x22, 0x8B, 0x22)); colorList.add(new ColorName("Fuchsia", 0xFF, 0x00, 0xFF)); colorList.add(new ColorName("Gainsboro", 0xDC, 0xDC, 0xDC)); colorList.add(new ColorName("GhostWhite", 0xF8, 0xF8, 0xFF)); colorList.add(new ColorName("Gold", 0xFF, 0xD7, 0x00)); colorList.add(new ColorName("GoldenRod", 0xDA, 0xA5, 0x20)); colorList.add(new ColorName("Gray", 0x80, 0x80, 0x80)); colorList.add(new ColorName("Green", 0x00, 0x80, 0x00)); colorList.add(new ColorName("GreenYellow", 0xAD, 0xFF, 0x2F)); colorList.add(new ColorName("HoneyDew", 0xF0, 0xFF, 0xF0)); colorList.add(new ColorName("HotPink", 0xFF, 0x69, 0xB4)); colorList.add(new ColorName("IndianRed", 0xCD, 0x5C, 0x5C)); colorList.add(new ColorName("Indigo", 0x4B, 0x00, 0x82)); colorList.add(new ColorName("Ivory", 0xFF, 0xFF, 0xF0)); colorList.add(new ColorName("Khaki", 0xF0, 0xE6, 0x8C)); colorList.add(new ColorName("Lavender", 0xE6, 0xE6, 0xFA)); colorList.add(new ColorName("LavenderBlush", 0xFF, 0xF0, 0xF5)); colorList.add(new ColorName("LawnGreen", 0x7C, 0xFC, 0x00)); colorList.add(new ColorName("LemonChiffon", 0xFF, 0xFA, 0xCD)); colorList.add(new ColorName("LightBlue", 0xAD, 0xD8, 0xE6)); colorList.add(new ColorName("LightCoral", 0xF0, 0x80, 0x80)); colorList.add(new ColorName("LightCyan", 0xE0, 0xFF, 0xFF)); colorList.add(new ColorName("LightGoldenRodYellow", 0xFA, 0xFA, 0xD2)); colorList.add(new ColorName("LightGray", 0xD3, 0xD3, 0xD3)); colorList.add(new ColorName("LightGreen", 0x90, 0xEE, 0x90)); colorList.add(new ColorName("LightPink", 0xFF, 0xB6, 0xC1)); colorList.add(new ColorName("LightSalmon", 0xFF, 0xA0, 0x7A)); colorList.add(new ColorName("LightSeaGreen", 0x20, 0xB2, 0xAA)); colorList.add(new ColorName("LightSkyBlue", 0x87, 0xCE, 0xFA)); colorList.add(new ColorName("LightSlateGray", 0x77, 0x88, 0x99)); colorList.add(new ColorName("LightSteelBlue", 0xB0, 0xC4, 0xDE)); colorList.add(new ColorName("LightYellow", 0xFF, 0xFF, 0xE0)); colorList.add(new ColorName("Lime", 0x00, 0xFF, 0x00)); colorList.add(new ColorName("LimeGreen", 0x32, 0xCD, 0x32)); colorList.add(new ColorName("Linen", 0xFA, 0xF0, 0xE6)); colorList.add(new ColorName("Magenta", 0xFF, 0x00, 0xFF)); colorList.add(new ColorName("Maroon", 0x80, 0x00, 0x00)); colorList.add(new ColorName("MediumAquaMarine", 0x66, 0xCD, 0xAA)); colorList.add(new ColorName("MediumBlue", 0x00, 0x00, 0xCD)); colorList.add(new ColorName("MediumOrchid", 0xBA, 0x55, 0xD3)); colorList.add(new ColorName("MediumPurple", 0x93, 0x70, 0xDB)); colorList.add(new ColorName("MediumSeaGreen", 0x3C, 0xB3, 0x71)); colorList.add(new ColorName("MediumSlateBlue", 0x7B, 0x68, 0xEE)); colorList.add(new ColorName("MediumSpringGreen", 0x00, 0xFA, 0x9A)); colorList.add(new ColorName("MediumTurquoise", 0x48, 0xD1, 0xCC)); colorList.add(new ColorName("MediumVioletRed", 0xC7, 0x15, 0x85)); colorList.add(new ColorName("MidnightBlue", 0x19, 0x19, 0x70)); colorList.add(new ColorName("MintCream", 0xF5, 0xFF, 0xFA)); colorList.add(new ColorName("MistyRose", 0xFF, 0xE4, 0xE1)); colorList.add(new ColorName("Moccasin", 0xFF, 0xE4, 0xB5)); colorList.add(new ColorName("NavajoWhite", 0xFF, 0xDE, 0xAD)); colorList.add(new ColorName("Navy", 0x00, 0x00, 0x80)); colorList.add(new ColorName("OldLace", 0xFD, 0xF5, 0xE6)); colorList.add(new ColorName("Olive", 0x80, 0x80, 0x00)); colorList.add(new ColorName("OliveDrab", 0x6B, 0x8E, 0x23)); colorList.add(new ColorName("Orange", 0xFF, 0xA5, 0x00)); colorList.add(new ColorName("OrangeRed", 0xFF, 0x45, 0x00)); colorList.add(new ColorName("Orchid", 0xDA, 0x70, 0xD6)); colorList.add(new ColorName("PaleGoldenRod", 0xEE, 0xE8, 0xAA)); colorList.add(new ColorName("PaleGreen", 0x98, 0xFB, 0x98)); colorList.add(new ColorName("PaleTurquoise", 0xAF, 0xEE, 0xEE)); colorList.add(new ColorName("PaleVioletRed", 0xDB, 0x70, 0x93)); colorList.add(new ColorName("PapayaWhip", 0xFF, 0xEF, 0xD5)); colorList.add(new ColorName("PeachPuff", 0xFF, 0xDA, 0xB9)); colorList.add(new ColorName("Peru", 0xCD, 0x85, 0x3F)); colorList.add(new ColorName("Pink", 0xFF, 0xC0, 0xCB)); colorList.add(new ColorName("Plum", 0xDD, 0xA0, 0xDD)); colorList.add(new ColorName("PowderBlue", 0xB0, 0xE0, 0xE6)); colorList.add(new ColorName("Purple", 0x80, 0x00, 0x80)); colorList.add(new ColorName("Red", 0xFF, 0x00, 0x00)); colorList.add(new ColorName("RosyBrown", 0xBC, 0x8F, 0x8F)); colorList.add(new ColorName("RoyalBlue", 0x41, 0x69, 0xE1)); colorList.add(new ColorName("SaddleBrown", 0x8B, 0x45, 0x13)); colorList.add(new ColorName("Salmon", 0xFA, 0x80, 0x72)); colorList.add(new ColorName("SandyBrown", 0xF4, 0xA4, 0x60)); colorList.add(new ColorName("SeaGreen", 0x2E, 0x8B, 0x57)); colorList.add(new ColorName("SeaShell", 0xFF, 0xF5, 0xEE)); colorList.add(new ColorName("Sienna", 0xA0, 0x52, 0x2D)); colorList.add(new ColorName("Silver", 0xC0, 0xC0, 0xC0)); colorList.add(new ColorName("SkyBlue", 0x87, 0xCE, 0xEB)); colorList.add(new ColorName("SlateBlue", 0x6A, 0x5A, 0xCD)); colorList.add(new ColorName("SlateGray", 0x70, 0x80, 0x90)); colorList.add(new ColorName("Snow", 0xFF, 0xFA, 0xFA)); colorList.add(new ColorName("SpringGreen", 0x00, 0xFF, 0x7F)); colorList.add(new ColorName("SteelBlue", 0x46, 0x82, 0xB4)); colorList.add(new ColorName("Tan", 0xD2, 0xB4, 0x8C)); colorList.add(new ColorName("Teal", 0x00, 0x80, 0x80)); colorList.add(new ColorName("Thistle", 0xD8, 0xBF, 0xD8)); colorList.add(new ColorName("Tomato", 0xFF, 0x63, 0x47)); colorList.add(new ColorName("Turquoise", 0x40, 0xE0, 0xD0)); colorList.add(new ColorName("Violet", 0xEE, 0x82, 0xEE)); colorList.add(new ColorName("Wheat", 0xF5, 0xDE, 0xB3)); colorList.add(new ColorName("White", 0xFF, 0xFF, 0xFF)); colorList.add(new ColorName("WhiteSmoke", 0xF5, 0xF5, 0xF5)); colorList.add(new ColorName("Yellow", 0xFF, 0xFF, 0x00)); colorList.add(new ColorName("YellowGreen", 0x9A, 0xCD, 0x32)); return colorList; } /** * Get the closest color name from our list * * @param r * @param g * @param b * @return */ public String getColorNameFromRgb(int r, int g, int b) { ArrayList colorList = initColorList(); ColorName closestMatch = null; int minMSE = Integer.MAX_VALUE; int mse; for (ColorName c : colorList) { mse = c.computeMSE(r, g, b); if (mse < minMSE) { minMSE = mse; closestMatch = c; } } if (closestMatch != null) { return closestMatch.getName(); } else { return "No matched color name."; } } /** * Convert hexColor to rgb, then call getColorNameFromRgb(r, g, b) * * @param hexColor * @return */ public String getColorNameFromHex(int hexColor) { int r = (hexColor & 0xFF0000) >> 16; int g = (hexColor & 0xFF00) >> 8; int b = (hexColor & 0xFF); return getColorNameFromRgb(r, g, b); } public int colorToHex(Color c) { return Integer.decode("0x" + Integer.toHexString(c.getRGB()).substring(2)); } public String getColorNameFromColor(Color color) { return getColorNameFromRgb(color.getRed(), color.getGreen(), color.getBlue()); } /** * SubClass of ColorUtils. In order to lookup color name * * @author Xiaoxiao Li * */ public class ColorName { public int r, g, b; public String name; public ColorName(String name, int r, int g, int b) { this.r = r; this.g = g; this.b = b; this.name = name; } public int computeMSE(int pixR, int pixG, int pixB) { return (int) (((pixR - r) * (pixR - r) + (pixG - g) * (pixG - g) + (pixB - b) * (pixB - b)) / 3); } public int getR() { return r; } public int getG() { return g; } public int getB() { return b; } public String getName() { return name; } } } 

Hmm, isso é um tipo de problema divertido. Eu posso pensar em algumas soluções:

  1. Você poderia fazer um pouco de adivinhação dependendo das relações entre os valores RGB (por exemplo, se uma cor é muito dominante, você adivinha isso, mas se houver um pouco de outra cor, você terá mais e mais probabilidade de adivinhar a combinação daqueles duas colors emitidas, se todas as três forem próximas, adivinhe branco, cinza ou preto, dependendo de quão alta a média dos três valores é, se duas são altas e a outra é baixa, acertar a combinação das duas, etc. .)

  2. Você poderia optar por uma abordagem mais de aprendizado, em que você definisse algumas suposições iniciais (como acima) e, em seguida, melhorasse aquelas com base no feedback dos usuários.

Infelizmente, esse problema é relativamente subjetivo (embora a questão não seja!), Pois a percepção das pessoas sobre a cor varia muito entre a cultura e até mesmo o gênero (ver “estudo” de Randall Munroe sobre ela ).

Se você quiser um subconjunto específico de valores RGB (como aqueles que recebem constantes em Java ou C #, você pode iterar cada um e comparar, finalmente retornando algum valor padrão se não for igual a nenhum deles).

[EDITAR]

Ahh! Usuários daltônicos eh? Você já pensou em criar uma configuração que permita ao usuário especificar quais colors eles têm dificuldade em diferenciar? Se você fez isso, você poderia informá-los de que algo é “20% mais vermelho que verde” (se, por exemplo, eles tivessem daltolho vermelho-verde, o que é mais comum). Isso seria bem simples. Eles selecionam um pixel e você segue esse pseudocódigo:

 if( userColorTrouble == RedGreen ) { int redVal = colorInQuestion.GetRed(); int greenVal = colorInQuestion.GetGreen(); if( redVal > greenVal ) { return "The color is " + (double)redVal / (redVal + greenVal) - .5d + "% redder than green"; } else { return "The color is " + (double)greenVal / (redVal + greenVal) - .5d + "% greener than red"; } } 

Essa poderia ser uma solução mais simples e mais útil.

Nem todos os valores RGB possuem aliases. Talvez seja necessário criar uma matriz contendo matrizes de valores Red, Green, Blue e Alias. Então você iria iterar sobre esse array comparando os valores RGB.

http://en.wikipedia.org/wiki/List_of_colors

Editar:

Amostra:

 //array of known aliases and rgb values ArrayList colorList = new ArrayList(); colorList.add(new String[] {"255", "0", "0", "Red"}); //etc... Color c = new Color(255, 0, 0); //test color String name = "Unknown"; for (String[] color : colorList) { int r = Integer.parseInt(color[0]) //red value int g = Integer.parseInt(color[1]) //green value int b = Integer.parseInt(color[2]) //blue value String alias = color[3]; if ((c.getRed() == r) && (c.getGreen() == g) && (c.getBlue() == b)) { name = alias; //found it break; } } 

Frist de todos os pixels de conversão de RGB para HSV. É muito mais fácil definir intervalos de colors no HSV do que no RGB.

 /** * *@author Tomasz Drobiszewski */ public class Color { /** * Human color table. */ public static final int [] [] colors = { {-1,-10,-360,-0,-100,-10,-80}, {1,0,360,0,100,0,50}, {2,0,360,0,15,50,130}, {3,0,360,0,15,130,210}, {4,-15,15,15,100,50,255}, {5,15,45,15,100,50,255}, {6,45,75,15,100,50,255}, {7,75,105,15,100,50,255}, {8,105,135,15,100,50,255}, {9,135,165,15,100,50,255}, {10,165,195,15,100,50,255}, {11,195,225,15,100,50,255}, {12,225,255,15,100,50,255}, {13,255,285,15,100,50,255}, {14,285,315,15,100,50,255}, {15,315,345,15,100,50,255}, {16,345,375,15,100,50,255}, {17,0,360,0,15,210,255} }; /** * Color names. */ public static final String [] humanColors = { "unrecognized", "black", //black colors[1] "grey", "light_grey", "red", "orange", "yellow", "jasny_zielony", "zielony", "zielony", "turkusowy", "jasny_niebieski", "niebieski", "fioletowy", "fioletowy", "rozowy", "czerwony", "bialy", }; /** * Convert from RGB do HSV * * @param r * @param g * @param b * @param hsv */ public static void rgb2hsv(int r, int g, int b, int hsv[]) { int min; // Min. value of RGB int max; // Max. value of RGB int delMax; // Delta RGB value if (r > g) { min = g; max = r; } else { min = r; max = g; } if (b > max) max = b; if (b < min) min = b; delMax = max - min; float H = 0, S; float V = max; if (delMax == 0) { H = 0; S = 0; } else { S = delMax / (float) max; if (r == max) H = ((g - b) / (float) delMax) * 60; else if (g == max) H = (2 + (b - r) / (float) delMax) * 60; else if (b == max) H = (4 + (r - g) / (float) delMax) * 60; } hsv[0] = (int) (H); hsv[1] = (int) (S * 100); hsv[2] = (int) V; } /** * Return human color index {@link Color#colors} * * @param r * @param g * @param b * @return */ public static int [] getHumanColor(int r, int g, int b) { int [] res = {0, 0, 0, 0}; int[] hsv = new int[3]; rgb2hsv(r, g, b, hsv); for (int i = 1; i < colors.length; i++) { if (hsv[0] <= colors[i][2] && hsv[0] >= colors[i][1] && hsv[1] <= colors[i][4] && hsv[1] >= colors[i][3] && hsv[2] <= colors[i][6] && hsv[2] >= colors[i][5]) { res[3] = i; res[0] = hsv[0]; res[1] = hsv[1]; res[2] = hsv[2]; return res; } } return res; } } 

Você poderia simplesmente criar uma tabela de pesquisa, por exemplo, usando as constantes da própria class Color:

 Map map = new HashMap(); for (Field f : Color.class.getFields()) { if (f.getType() == Color.class) { Color c = (Color) f.get(null); map.put(c.getRGB(), f.getName()); } } 

Se você quiser todas as colors HTML ou todas as formas da Wikipedia ligadas por @evan, você ainda tem um pouco de lição de casa para fazer.

EDIT mapa resultante:

 0xff00ffff: CYAN 0xff0000ff: BLUE 0xffc0c0c0: LIGHT_GRAY 0xff808080: GRAY 0xffffff00: YELLOW 0xffff0000: RED 0xffffafaf: PINK 0xff000000: BLACK 0xff00ff00: GREEN 0xffffc800: ORANGE 0xff404040: DARK_GRAY 0xffff00ff: MAGENTA 0xffffffff: WHITE 

No meu caso, eu estava procurando uma maneira rápida de exibir o nome das colors primárias em todos ou todos os LEDs, para que a function a seguir funcione para mim. Espero que seja útil para alguém.

 public static String getColourName(int c) { String name = "UNKNOWN"; int colour = Color.BLACK; if(Color.red(c) > 127) { colour |= Color.RED; } if(Color.green(c) > 127) { colour |= Color.GREEN; } if(Color.blue(c) > 127) { colour |= Color.BLUE; } switch (colour) { case Color.BLACK: name = "BLACK"; break; case Color.BLUE: name = "BLUE"; break; case Color.GREEN: name = "GREEN"; break; case Color.CYAN: name = "CYAN"; break; case Color.RED: name = "RED"; break; case Color.MAGENTA: name = "MAGENTA"; break; case Color.YELLOW: name = "YELLOW"; break; case Color.WHITE: name = "WHITE"; break; } return name; }