Konwertuj System.Drawing.Color na wartość RGB i wartość szesnastkową


125

Używając C #, próbowałem rozwinąć następujące dwa. Sposób, w jaki to robię, może mieć jakiś problem i potrzebować twojej życzliwej rady. Poza tym nie wiem, czy istnieje jakaś metoda, aby zrobić to samo.

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

Dzięki.


Odpowiedzi:


202

Nie widzę tutaj problemu. Według mnie kod wygląda dobrze.

Jedyną rzeczą, którą mogę pomyśleć, to że try / catch bloki są zbędne - Kolor jest struktura i R, G i B są bajty, więc c nie może być null i c.R.ToString(), c.G.ToString()i c.B.ToString()nie może faktycznie uda (the Jedynym sposobem, w jaki mogę zobaczyć, jak zawodzą, jestNullReferenceException , a żadne z nich nie może być w rzeczywistości zerowe).

Możesz wszystko wyczyścić za pomocą:

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
Posunąłbym się nawet do stwierdzenia, że ​​puste bloki try-catch powinny (prawie) powszechnie zostać wyeliminowane. Mają duży potencjał, aby doprowadzić do błędnego kodu, jeśli nie teraz, to w przyszłości, gdy ten kod zostanie zmodyfikowany. Mimo to +1 za oczyszczony kod i do OP +1 za dobrze sformułowane pytanie.
JMD

7
Zajęło mi trochę czasu, zanim znalazłem odpowiednik VB: String.Format ("# {0: X2} {1: X2} {2: X2}", cR, cG, cB)
zacharydl

1
Jako alternatywną odpowiedź zamieszczam adaptację twojego kodu do C # 6. Możesz to zobaczyć tutaj .
aloisdg przenosi się na codidact.com

Spowoduje to powstanie niewłaściwego koloru, jeśli kolor ma kanał alfa (przezroczystość). Otrzymasz pełną nieprzejrzystość.
LarryBud,

@LarryBud Absolutnie prawdziwe i dziękuję za wskazanie tego. W moim przykładzie pominięto kanał alfa tylko dlatego, że wyłączałem pierwotne pytanie, które również go nie zawierało. :)
Ari Roth

189

Możesz zachować prostotę i użyć rodzimego translatora kolorów:

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

Następnie podziel te trzy pary kolorów na postać całkowitą:

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

7
Ale jeśli zrobię w ten sposób, Color red = System.Drawing.Color.Red; string redHex = ColorTranslator.ToHtml (czerwony); nie podaje wartości szesnastkowej.
Nazmul

Z pewnością powinienem, przetestowałem ten kod specjalnie i otrzymałem # „FF0000”. Co otrzymujesz? Możesz również skorzystać z referencji MSDN: msdn.microsoft.com/en-us/library/…
Troy Hunt

Spróbuj z kolorem czerwonym = System.Drawing.Color.Red; -> nie zawiera # FF0000.
Nazmul

9
Kod, który podałeś, działa, ale kiedy zmienię pierwszy wiersz twojego kodu na: Color red = System.Drawing.Color.Red; -> Wtedy nie podaje kodu szesnastkowego. Daje "Czerwony" jako wynik.
Nazmul

4
@Hoque - potwierdzone. ColorTranslator nadaje kolorowi „przyjazną” nazwę. Jakie to irytujące!
anon

38

Jeśli możesz używać C # 6 lub nowszego, możesz skorzystać z interpolowanych ciągów i przepisać rozwiązanie @Ari Roth w następujący sposób:

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

Również:

  • Dodaję słowo kluczowe, thisaby użyć ich jako metod rozszerzających.
  • Możemy użyć słowa kluczowego type string zamiast nazwy klasy.
  • Możemy użyć składni lambda.
  • Zmieniam ich nazwę, aby była bardziej wyraźna według mojego gustu.

Tak czysty ... +1!
Shockwaver

26

na przykład

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

Pozwala to uniknąć sztuczki KnownColor.


1

Znalazłem metodę rozszerzenia, która działa całkiem dobrze

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


Uważam, że powinien to być Hex2, a nie Hex, w przeciwnym razie kolor może być źle interpolowany.
Mohammed Noureldin

@MohammedNoureldin Gdzie miałby się znaleźć Hex2 w kodzie, widziałem czasami, że kolory są nieco inne?
user1

Miałem na myśli X2zamiast X, w przeciwnym razie możesz dostać 1zamiast, 01wtedy będzie problem.
Mohammed Noureldin

@MohammedNoureldin Yeah, X2wtedy nie potrzebujesz wszystkich color.B.ToString("X").Length == 1 ? ternaries.
ProfK

1

W przypadku kodu szesnastkowego spróbuj tego

  1. Uzyskaj reprezentację ARGB (Alpha, Red, Green, Blue) dla koloru
  2. Odfiltruj kanał alfa:& 0x00FFFFFF
  3. Sformatuj wartość (jako szesnastkowy „X6” dla szesnastkowego)

Dla jednego RGB

  1. Wystarczy sformatować out Red , Green, Bluewartości

Realizacja

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);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.