2012-07-30 15 views
13

Estoy creando una aplicación para encontrar el color más usado de una imagen, estoy listo para obtener el valor RGB del color, pero cómo obtener el nombre del color, ayuda por favor.¿Cómo obtener el nombre del color mientras tiene su valor RGB en C#?

+2

Puede ser esto ayuda, http://stackoverflow.com/questions/365935/trying-to-convert-rgb-from-a-net-color-to-a-string-such-as-red-or- azul – Habib

+0

[¿Qué has probado] (http://whathaveyoutried.com)? ¿Dónde estás atrapado? ¿Qué esperas que suceda cuando el color no es uno de los conocidos? – Oded

Respuesta

2

Debería poder utilizar la clase Color del espacio de nombres System.Drawing, tiene un método estático FromARGB que devuelve un objeto Color. Tiene varias sobrecargas, uno que le permite introducir los valores RGB de este modo:

var color = Color.FromArgb(100, 5,5,5).Name; 
+0

De la documentación: 'Este método devuelve el nombre del color definido por el usuario, si el color se creó a partir de un nombre o el nombre del color conocido. Para colores personalizados, se devuelve el valor RGB. –

+3

** No ** devuelve el nombre en el formato "Rojo". Para su ejemplo, el nombre aparece como 64050505. – adrianbanks

+0

sí, está dando el valor hexadecimal, ¿cómo obtener el nombre? – fresky

11

Este método utiliza la reflexión para examinar los colores predefinidos en la clase Color y compararlos con el color pasado como argumento. Esto se puede optimizar aún más, pero debería darle una idea de la técnica general.

private static String GetColorName(Color color) 
{ 
    var predefined = typeof(Color).GetProperties(BindingFlags.Public | BindingFlags.Static); 
    var match = (from p in predefined where ((Color)p.GetValue(null, null)).ToArgb() == color.ToArgb() select (Color)p.GetValue(null, null)); 
    if (match.Any()) 
     return match.First().Name; 
    return String.Empty; 
} 
+0

En lugar de 'Any',' First', llame a 'FirstOrDefault' y luego verifique si el resultado es nulo. –

+2

El color es una estructura. FirstOrDefault devolverá un color vacío, no nulo. –

20

Como se señaló en los comentarios, la KnownColor enumeración puede ser utilizado para hacer esta simple:

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Color color = Color.FromArgb(255, 0, 0); 
     Console.WriteLine(color.Name); // ffff0000 

     var colorLookup = Enum.GetValues(typeof(KnownValue)) 
       .Cast<KnownColor>() 
       .Select(Color.FromKnownColor) 
       .ToLookup(c => c.ToArgb()); 

     // There are some colours with multiple entries... 
     foreach (var namedColor in colorLookup[color.ToArgb()]) 
     { 
      Console.WriteLine(namedColor.Name); 
     } 
    } 
} 

Respuesta original

Color.FromArgb le dará una Color, pero nunca tendrá un nombre. Necesitas usar reflejo para obtener los colores nombrados, que yo sepa.

Aquí hay otra versión de la solución de Cole Campbell, que estaba trabajando al mismo tiempo ...

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Color color = Color.FromArgb(255, 0, 0); 
     Console.WriteLine(color.Name); // ffff0000 

     var colorLookup = typeof(Color) 
       .GetProperties(BindingFlags.Public | BindingFlags.Static) 
       .Select(f => (Color) f.GetValue(null, null)) 
       .Where(c => c.IsNamedColor) 
       .ToLookup(c => c.ToArgb()); 

     // There are some colours with multiple entries... 
     foreach (var namedColor in colorLookup[color.ToArgb()]) 
     { 
      Console.WriteLine(namedColor.Name); 
     } 
    } 
} 
+0

Puede usar la [enumeración KnownColor] (https://msdn.microsoft.com/en-us/library/system.drawing.knowncolor (v = vs.110) .aspx? Cs-lang = csharp # code-snippet -2) para evitar la reflexión. –

+0

@AndrewMorton: Buen punto - editado. –

+0

'KnownColor' no es realmente útil en este caso, porque también contiene colores del sistema como' ActiveCaptionText'. Por lo tanto, este método también devolverá estos nombres. – Karsten

0

Para algo rápido y sencillo, probar este (en WPF):

public string GetNameOfColor(Color color) { 
    var colorProperty = typeof(Colors).GetProperties().FirstOrDefault(p => 
     (Color)(p.GetValue(p, null)) == color); 
    return (colorProperty != null) ? colorProperty.Name : color.ToString(); 
} 

En Visual Studio 2010, se requiere p.GetValue(p, null). En Visual Studio 2013+ puede simplemente usar p.GetValue(p).

La ventaja de esta técnica, además de su brevedad, es que no requiere referencias a System.Drawing o System.Reflection pero permite al usuario permanecer en el interior del espacio de nombres System.Windows, que es WPF. Requiere una referencia al System.Windows.Media que probablemente ya debería tener si está trabajando con Colors en WPF. Si es como yo, intente no agregar System.Drawing a sus aplicaciones WPF sin una buena necesidad. En cuanto a por qué permanecer dentro del espacio de nombres de WPF, es una cuestión de preferencia. Ver por ejemplo las discusiones en WPF v/s System.Drawing.

+0

¿En qué se diferencia esto de las otras dos respuestas y de qué parte es WPF? –

Cuestiones relacionadas