Converti System.Drawing.Color in RGB e valore esadecimale


125

Usando C # stavo cercando di sviluppare i seguenti due. Il modo in cui lo sto facendo potrebbe avere qualche problema e avere bisogno del tuo gentile consiglio. Inoltre, non so se esiste un metodo esistente per fare lo stesso.

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;
}

Grazie.


Risposte:


202

Non riesco a vedere il problema qui. Il codice mi sembra buono.

L'unica cosa che posso pensare è che i try / blocchi catch sono ridondanti - colore è una struct e R, G, B e sono byte, così c non può essere nullo e c.R.ToString(), c.G.ToString()e c.B.ToString()non può realmente sicuro (la l'unico modo in cui riesco a vederli fallire è con a NullReferenceException, e nessuno di loro può effettivamente essere nullo).

Puoi pulire tutto usando il seguente:

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() + ")";
}

1
Andrei al punto di dire che i blocchi vuoti try-catch dovrebbero (quasi) universalmente essere sradicati. Hanno un grande potenziale per portare al codice errato, se non ora in fondo alla strada quando questo codice viene modificato. Tuttavia, +1 per il codice ripulito e OP +1 per una domanda ben strutturata.
JMD,

7
Mi ci è voluto un po 'per trovare l'equivalente VB: String.Format ("# {0: X2} {1: X2} {2: X2}", cR, cG, cB)
zacharydl

1
Pubblico un adattamento del codice a C # 6 come risposta alternativa. Puoi vederlo qui .
aloisdg si trasferisce su codidact.com il

Questo produrrà il colore sbagliato se il colore ha un canale alfa (trasparenza). Otterrai la completa opacità.
LarryBud,

@LarryBud Assolutamente vero, e grazie per averlo sottolineato. Il mio esempio ha ignorato il canale alfa solo perché stavo cancellando la domanda originale, che non lo includeva. :)
Ari Roth,

189

Potresti mantenerlo semplice e utilizzare il traduttore di colori nativo:

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

Quindi suddividere le tre coppie di colori in forma intera:

int value = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);

7
Ma se lo faccio in questo modo, Colore rosso = System.Drawing.Color.Red; string redHex = ColorTranslator.ToHtml (rosso); non fornisce il valore esadecimale.
Nazmul

Certamente dovrebbe, ho testato quel codice in modo specifico e ho ottenuto # "FF0000". Che cosa stai ottenendo? Potresti anche fare riferimento al riferimento MSDN: msdn.microsoft.com/en-us/library/…
Troy Hunt

Prova con Colore rosso = System.Drawing.Color.Red; -> non fornisce # FF0000.
Nazmul

9
Il codice che hai fornito funziona ma quando cambio la prima riga del codice in: Colore rosso = System.Drawing.Color.Red; -> Quindi non fornisce il codice esadecimale. Dà "Rosso" come output.
Nazmul,

4
@Hoque - Confermato. ColorTranslator dà un nome "amichevole" al colore. Che noioso!
anon

38

Se puoi usare C # 6 o versioni successive, puoi beneficiare delle stringhe interpolate e riscrivere la soluzione di @Ari Roth in questo modo:

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})";
}

Anche:

  • Aggiungo la parola chiave thisper usarli come metodi di estensione.
  • Possiamo usare la parola chiave type stringanziché il nome della classe.
  • Possiamo usare la sintassi lambda.
  • Li rinominare per essere più espliciti per i miei gusti.

Così pulito ... +1!
Shockwaver il

26

per esempio

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

Questo può evitare il trucco di KnownColor.


1

Ho trovato un metodo di estensione che funziona abbastanza bene

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"));
}

Rif: 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


Credo che dovrebbe essere Hex2, non Hex, altrimenti il ​​colore potrebbe essere errato interpolato.
Mohammed Noureldin,

@MohammedNoureldin Dove andrebbe Hex2 nel codice, a volte ho visto colori leggermente diversi?
user1

Volevo dire X2invece di X, altrimenti potresti ottenere 1invece di 01allora sarà un problema.
Mohammed Noureldin,

@MohammedNoureldin Sì, con X2allora non hai bisogno di tutti i color.B.ToString("X").Length == 1 ? ternari.
ProfK,

1

Per il codice esadecimale, prova questo

  1. Ottieni la rappresentazione ARGB (Alpha, Red, Green, Blue) per il colore
  2. Filtra il canale alfa:& 0x00FFFFFF
  3. Formatta il valore (come esadecimale "X6" per hex)

Per RGB uno

  1. Basta formattare out Red , Green, Bluevalori

Implementazione

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.