153

Using C# I was trying to develop the following two. The way I am doing it may have some problem and need your kind advice. In addition, I dont know whether there is any existing method to do the same.

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

Thanks.

Nazmul
  • 7,078
  • 12
  • 51
  • 63

6 Answers6

254

I'm failing to see the problem here. The code looks good to me.

The only thing I can think of is that the try/catch blocks are redundant -- Color is a struct and R, G, and B are bytes, so c can't be null and c.R.ToString(), c.G.ToString(), and c.B.ToString() can't actually fail (the only way I can see them failing is with a NullReferenceException, and none of them can actually be null).

You could clean the whole thing up using the following:

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() + ")";
}
Crown
  • 169
  • 1
  • 7
Ari Roth
  • 5,392
  • 2
  • 31
  • 46
  • 2
    I'd go so far as to say that empty try-catch blocks should (almost) universally be eradicated. They have great potential to lead to buggy code, if not now then down the road when this code is modified. Still, +1 for the cleaned up code, and to the OP +1 for a well-framed question. – JMD Jun 03 '14 at 14:32
  • 11
    Took me a while to find the VB equivelant: String.Format("#{0:X2}{1:X2}{2:X2}", c.R, c.G, c.B) – zacharydl Jun 30 '14 at 19:37
  • 2
    I post an adaptation of your code to C#6 as an alternative answer. You can see it [here](http://stackoverflow.com/a/37821008/1248177). – aloisdg Jun 14 '16 at 19:59
  • This will produce the wrong color if the color has an alpha channel (transparency). You will get full opaqueness. – LarryBud Feb 12 '19 at 13:09
  • @LarryBud Absolutely true, and thank you for pointing it out. My example skipped the alpha channel only because I was keying off of the original question, which also didn't include it. :) – Ari Roth Apr 05 '19 at 19:29
  • @LarryBud [this answer](http://stackoverflow.com/a/37821008/1248177) supports alpha channel – aloisdg Jan 11 '23 at 20:21
218

You could keep it simple and use the native color translator:

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

Then break the three color pairs into integer form:

int value = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
Troy Hunt
  • 20,345
  • 13
  • 96
  • 151
  • 9
    But if I do this way, Color red = System.Drawing.Color.Red; string redHex = ColorTranslator.ToHtml(red); it does not provide the Hex Value. – Nazmul Mar 07 '10 at 07:29
  • Certainly should do, I tested that code specifically and got #"FF0000". What are you getting? You might also like to refer to the MSDN reference: http://msdn.microsoft.com/en-us/library/system.drawing.colortranslator.tohtml.aspx – Troy Hunt Mar 07 '10 at 07:45
  • Try with Color red = System.Drawing.Color.Red; --> it does not provide #FF0000. – Nazmul Mar 07 '10 at 08:31
  • So using exactly the first code block I provided, what is the value of redHex? I think something on your side is missing. – Troy Hunt Mar 07 '10 at 10:27
  • 9
    The code you have provided works but when I change the first line of your code to : Color red = System.Drawing.Color.Red; --> Then it does not give the hex code. It gives "Red" as an output. – Nazmul Mar 07 '10 at 11:33
  • 5
    @Hoque - Confirmed. ColorTranslator gives a "friendly" name to the color. How annoying! – anon Feb 17 '13 at 04:36
  • +1 bc this caused me to look at the .NET implementation of `ColorTranslator` which is the accepted answer + `KnownColor` logic. i didn't want that logic, so i went with the accepted answer (but made extension methods) – Brad Jul 07 '14 at 16:17
  • This may not be suitable for some cases, because a quick test within a WinForm lead to the following result: `System.Drawing.ColorTranslator.ToHtml(Me.BackColor) = "buttonface"` instead of the (desired) hex value. – mike Dec 15 '15 at 12:09
  • One other thing to be aware is that any `Alpha` values of your color are lost! – Crown Jan 12 '23 at 08:49
55

If you can use C#6 or higher, you can benefit from Interpolated Strings and rewrite @Ari Roth's solution like this:

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

Also:

  • I add the keyword this to use them as extensions methods.
  • We can use the type keyword string instead of the class name.
  • We can use lambda syntax.
  • I rename them to be more explicit for my taste.

Edit: If you want to support the alpha channel:

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

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

    // #RRGGBBAA
    public static string ToHexaString(this Color c) => $"#{c.R:X2}{c.G:X2}{c.B:X2}{c.A:X2}";

    private static double ToProportion(byte b) => b / (double)Byte.MaxValue;

    // RGBA(R, G, B, A)
    public static string ToRgbaString(this Color c) => $"RGBA({c.R}, {c.G}, {c.B}, {ToProportion(c.A):N2})";
}

Fun fact: I have to search about the proportion name, because we want for a value in the interval [0, 1] not a percent which is in the interval [0, 100]

aloisdg
  • 22,270
  • 6
  • 85
  • 105
34

e.g.

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

This can avoid the KnownColor trick.

Andy Fong
  • 428
  • 6
  • 15
3

I found an extension method that works quite well

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

JKennedy
  • 18,150
  • 17
  • 114
  • 198
3

For hexadecimal code try this

  1. Get ARGB (Alpha, Red, Green, Blue) representation for the color
  2. Filter out Alpha channel: & 0x00FFFFFF
  3. Format out the value (as hexadecimal "X6" for hex)

For RGB one

  1. Just format out Red, Green, Blue values

Implementation

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
  • 180,369
  • 20
  • 160
  • 215