c# .net image colors system.drawing.color

c# - tratando de convertir rgb de un color.net a una cadena como "rojo" o "azul"



image colors (5)

Personalmente, creo que es más natural pensar en los colores en términos de matiz / saturación / brillo que los valores RGB, y creo que en este caso funcionaría bien. Prueba esto:

Asigna nombres de colores a ciertos rangos del espectro, como mejor te parezca. Por ejemplo, tal vez el rojo es 0-39, el naranja es 40-79, etc. (esos son números arbitrarios, no tengo idea si encajan en cualquier tipo de escala o no). Luego calcule el tono de su valor RGB (aquí puede encontrar una fórmula, aunque puede haber otras). Una vez que conoces el tono, sabes en qué rango del espectro se encuentra, y puedes ponerle un nombre.

Todos mis métodos me están fallando de varias maneras. una iluminación diferente también puede estropearlo todo.

¿Alguien ha tratado de devolver un nombre dado un valor rgb? "rojo", "verde", "azul" sería suficiente para satisfacer mis necesidades de hoy.

Tengo un procesamiento de bytes inseguro de imágenes de mi cámara web.

webcam http://i35.tinypic.com/2yvorau.png


Bueno, Red / Green / Blue es bastante fácil de identificar por inspección; ¿Qué rango de valores necesitas para apoyar?

El problema es que a menos que empiece con un color con nombre, es muy difícil volver a uno; IsNamedColor devolverá falso incluso si crea un color obvio a través de FromArgb.

Si solo necesita los colores estándar reales esperados, puede enumerar los colores conocidos a través de la reflexión.

Color test = Color.FromArgb(255,0,0); Color known = ( from prop in typeof(Color) .GetProperties(BindingFlags.Public | BindingFlags.Static) where prop.PropertyType == typeof(Color) let color = (Color)prop.GetValue(null, null) where color.A == test.A && color.R == test.R && color.G == test.G && color.B == test.B select color) .FirstOrDefault(); Console.WriteLine(known.Name);

También es posible que pueda utilizar este enfoque como fuente de colores conocidos para un algoritmo más sofisticado.


Si tiene una lista de colores conocidos con nombres, puede ver cuál de esos colores conocidos es el más cercano al color objetivo dado, usando una función de "cercanía" en la línea de (código F #):

let Diff (c1:Color) (c2:Color) = let dr = (c1.R - c2.R) |> int let dg = (c1.G - c2.G) |> int let db = (c1.B - c2.B) |> int dr*dr + dg*dg + db*db

Cualquiera que sea el color conocido que tenga la diferencia más pequeña al color objetivo que desea nombrar, use ese nombre.


Puedes probar este código

static char[] hexDigits = { ''0'', ''1'', ''2'', ''3'', ''4'', ''5'', ''6'', ''7'', ''8'', ''9'', ''A'', ''B'', ''C'', ''D'', ''E'', ''F''}; public static string ColorToHexString(Color color) { byte[] bytes = new byte[4]; bytes[0] = color.A; bytes[1] = color.R; bytes[2] = color.G; bytes[3] = color.B; char[] chars = new char[bytes.Length * 2]; for (int i = 0; i < bytes.Length; i++) { int b = bytes[i]; chars[i * 2] = hexDigits[b >> 4]; chars[i * 2 + 1] = hexDigits[b & 0xF]; } return new string(chars); }


Aquí hay un esquema de nombre simple que usa dos calificadores y un nombre de color:

string ColorName(Color c) { List<float> hues = new List<float>() { 0, 15, 35, 44, 54, 63, 80, 160, 180, 200, 244, 280, 350, 360}; List<string> hueNames = new List<string>() { "red", "orange-red", "orange", "yellow-orange", "yellow", "yellow-green", "green" , "blue-green" , "cyan", "blue", "violet", "purple", "red" }; float h = c.GetHue(); float s = c.GetSaturation(); float b = (c.R * 0.299f + c.G * 0.587f + c.B *0.114f) / 256f; string name = s < 0.35f ? "pale " : s > 0.8f ? "vivid " : ""; name += b < 0.35f ? "dark " : b > 0.8f ? "light " : ""; for (int i = 0; i < hues.Count - 1; i++) if (h >= hues[i] && h <= hues[i+1] ) { name += hueNames[i]; break; } return name; }

Puedes adaptarlo fácilmente si quieres que los blues sean más diferenciados, etc.