Convert System.Drawing.Color to RGB and Hex Value
Solution 1
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() + ")";
}
Solution 2
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);
Solution 3
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}";
public 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]
- https://english.stackexchange.com/a/286524/70403
- https://english.stackexchange.com/questions/218655/a-number-between-0-and-1-like-a-percentage-but-expressed-as-a-decimal
- https://math.stackexchange.com/questions/890617/name-for-percentage-as-a-decimal-between-0-and-1-inclusive
- https://math.stackexchange.com/questions/1626783/is-there-a-name-for-numbers-between-0-and-1
Solution 4
e.g.
ColorTranslator.ToHtml(Color.FromArgb(Color.Tomato.ToArgb()))
This can avoid the KnownColor trick.
Solution 5
For hexadecimal code try this
- Get ARGB (Alpha, Red, Green, Blue) representation for the color
- Filter out Alpha channel:
& 0x00FFFFFF
- Format out the value (as hexadecimal "X6" for hex)
For RGB one
- 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);
}
Nazmul
When studying Mechanical Engineering, I had a course on FORTRAN and that basically inspire me to dive into field of Programming language. Signed in Stackoverflow almost 11 years ago and so far tried to help others and as well as receive awesome helps from other users. Born in Bangladesh and currently living in Canada. Like Bangladeshi curry and Japanese sushi.
Updated on July 08, 2022Comments
-
Nazmul almost 2 years
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.
-
samgak about 7 years
-
-
Nazmul over 14 yearsBut if I do this way, Color red = System.Drawing.Color.Red; string redHex = ColorTranslator.ToHtml(red); it does not provide the Hex Value.
-
Troy Hunt over 14 yearsCertainly should do, I tested that code specifically and got #"FF0000". What are you getting? You might also like to refer to the MSDN reference: msdn.microsoft.com/en-us/library/…
-
Nazmul over 14 yearsTry with Color red = System.Drawing.Color.Red; --> it does not provide #FF0000.
-
Troy Hunt over 14 yearsSo using exactly the first code block I provided, what is the value of redHex? I think something on your side is missing.
-
Nazmul over 14 yearsThe 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.
-
anon over 11 years@Hoque - Confirmed. ColorTranslator gives a "friendly" name to the color. How annoying!
-
JMD about 10 yearsI'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.
-
zacharydl about 10 yearsTook me a while to find the VB equivelant: String.Format("#{0:X2}{1:X2}{2:X2}", c.R, c.G, c.B)
-
Brad almost 10 years+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) -
mike over 8 yearsThis 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. -
aloisdg about 8 yearsI post an adaptation of your code to C#6 as an alternative answer. You can see it here.
-
Mohammed Noureldin over 6 yearsI belive it should be Hex2, not Hex, otherwise the color maybe wrong interpolated.
-
User1 over 6 years@MohammedNoureldin Where would Hex2 go in the code, I have seen colours being slightly different sometimes?
-
Mohammed Noureldin over 6 yearsI meant
X2
instead ofX
, otherwise you might get1
instead of01
then it will be a problem. -
LarryBud over 5 yearsThis will produce the wrong color if the color has an alpha channel (transparency). You will get full opaqueness.
-
Ari Roth about 5 years@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. :)
-
ProfK over 4 years@MohammedNoureldin Yeah, with
X2
then you don't need all thecolor.B.ToString("X").Length == 1 ?
ternaries. -
Shockwaver about 4 yearsSo clean... +1!
-
George Fabish over 2 yearsTo make this work with web browsers I had to switch the formatting so that the alpha parameter would be added last.