Convertir System.Drawing.Color a RGB y valor hexadecimal

125

Usando C # estaba tratando de desarrollar los siguientes dos. La forma en que lo estoy haciendo puede tener algún problema y necesitar su amable consejo. Además, no sé si existe algún método para hacer lo mismo.

private static String HexConverter(System.Drawing.Color c)
{
    String rtn = String.Empty;
    try
    {
        rtn = "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
    }
    catch (Exception ex)
    {
        //doing nothing
    }

    return rtn;
}

private static String RGBConverter(System.Drawing.Color c)
{
    String rtn = String.Empty;
    try
    {
        rtn = "RGB(" + c.R.ToString() + "," + c.G.ToString() + "," + c.B.ToString() + ")";
    }
    catch (Exception ex)
    {
        //doing nothing
    }

    return rtn;
}

Gracias.

Nazmul
fuente

Respuestas:

202

No puedo ver el problema aquí. El código me parece bien.

Lo único que ocurre es que los bloques try / catch son redundantes - El color es una estructura y R, G y B son bytes, por lo que c no puede ser nulo y c.R.ToString(), c.G.ToString()y c.B.ToString()en realidad no puede fallar (el La única forma en que puedo verlos fallar es con un NullReferenceException, y ninguno de ellos puede ser nulo).

Puedes limpiar todo usando lo siguiente:

private static String HexConverter(System.Drawing.Color c)
{
    return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}

private static String RGBConverter(System.Drawing.Color c)
{
    return "RGB(" + c.R.ToString() + "," + c.G.ToString() + "," + c.B.ToString() + ")";
}
Ari Roth
fuente
1
Llegaría al extremo de decir que los bloques vacíos try-catch deberían (casi) universalmente erradicarse. Tienen un gran potencial para conducir a un código defectuoso, si no ahora, en el futuro, cuando se modifique este código. Aún así, +1 para el código limpiado, y al OP +1 para una pregunta bien enmarcada.
JMD
77
Me tomó un tiempo encontrar el equivalente de VB: String.Format ("# {0: X2} {1: X2} {2: X2}", cR, cG, cB)
zacharydl
1
Publico una adaptación de su código a C # 6 como respuesta alternativa. Puedes verlo aquí .
aloisdg mover a codidact.com
Esto producirá el color incorrecto si el color tiene un canal alfa (transparencia). Obtendrá opacidad total.
LarryBud
@LarryBud Absolutamente cierto, y gracias por señalarlo. Mi ejemplo omitió el canal alfa solo porque estaba borrando la pregunta original, que tampoco la incluía. :)
Ari Roth
189

Puede hacerlo simple y usar el traductor de color nativo:

Color red = ColorTranslator.FromHtml("#FF0000");
string redHex = ColorTranslator.ToHtml(red);

Luego divida los tres pares de colores en forma entera:

int value = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
Troy Hunt
fuente
77
Pero si lo hago de esta manera, Color rojo = System.Drawing.Color.Red; cadena redHex = ColorTranslator.ToHtml (rojo); no proporciona el valor hexadecimal.
Nazmul
Ciertamente debería hacerlo, probé ese código específicamente y obtuve # "FF0000". ¿Que estas obteniendo? También puede consultar la referencia de MSDN: msdn.microsoft.com/en-us/library/…
Troy Hunt el
Pruebe con Color rojo = System.Drawing.Color.Red; -> no proporciona # FF0000.
Nazmul
9
El código que ha proporcionado funciona, pero cuando cambio la primera línea de su código a: Color rojo = System.Drawing.Color.Red; -> Entonces no da el código hexadecimal. Da "Rojo" como salida.
Nazmul
44
@Hoque - Confirmado. ColorTranslator le da un nombre "amigable" al color. ¡Que molesto!
anon
38

Si puede usar C # 6 o superior, puede beneficiarse de las cadenas interpoladas y reescribir la solución de @Ari Roth de esta manera:

C # 6:

public static class ColorConverterExtensions
{
    public static string ToHexString(this Color c) => $"#{c.R:X2}{c.G:X2}{c.B:X2}";

    public static string ToRgbString(this Color c) => $"RGB({c.R}, {c.G}, {c.B})";
}

También:

  • Agrego la palabra clave thispara usarlos como métodos de extensiones.
  • Podemos usar la palabra clave type en stringlugar del nombre de la clase.
  • Podemos usar la sintaxis lambda.
  • Los renombro para que sean más explícitos para mi gusto.
aloisdg moviéndose a codidact.com
fuente
Tan limpio ... +1!
Shockwaver
26

p.ej

 ColorTranslator.ToHtml(Color.FromArgb(Color.Tomato.ToArgb()))

Esto puede evitar el truco de KnownColor.

Andy Fong
fuente
1

Encontré un método de extensión que funciona bastante bien

public static string ToHex(this Color color)
{
    return String.Format("#{0}{1}{2}{3}"
        , color.A.ToString("X").Length == 1 ? String.Format("0{0}", color.A.ToString("X")) : color.A.ToString("X")
        , color.R.ToString("X").Length == 1 ? String.Format("0{0}", color.R.ToString("X")) : color.R.ToString("X")
        , color.G.ToString("X").Length == 1 ? String.Format("0{0}", color.G.ToString("X")) : color.G.ToString("X")
        , color.B.ToString("X").Length == 1 ? String.Format("0{0}", color.B.ToString("X")) : color.B.ToString("X"));
}

Ref: https://social.msdn.microsoft.com/Forums/en-US/4c77ba6c-6659-4a46-920a-7261dd4a15d0/how-to-convert-rgba-value-into-its-equivalent-hex-code? forum = winappswithcsharp

usuario1
fuente
Creo que debería ser Hex2, no Hex, de lo contrario el color puede estar mal interpolado.
Mohammed Noureldin
@MohammedNoureldin ¿Dónde iría Hex2 en el código, he visto que los colores son ligeramente diferentes a veces?
usuario1
Quise decir en X2lugar de X, de lo contrario podría obtener en 1lugar de 01entonces será un problema.
Mohammed Noureldin
@MohammedNoureldin Sí, con X2eso no necesitas todos los color.B.ToString("X").Length == 1 ? ternaries.
ProfK
1

Para el código hexadecimal intente esto

  1. Obtenga representación ARGB (Alfa, Rojo, Verde, Azul) para el color
  2. Filtrar el canal alfa:& 0x00FFFFFF
  3. Formatee el valor (como hexadecimal "X6" para hexadecimal)

Para RGB uno

  1. Sólo formatear cabo Red , Green, Bluevalores

Implementación

private static string HexConverter(Color c) {
  return String.Format("#{0:X6}", c.ToArgb() & 0x00FFFFFF);
}

public static string RgbConverter(Color c) {
  return String.Format("RGB({0},{1},{2})", c.R, c.G, c.B);
}
Dmitry Bychenko
fuente