Wednesday, March 18, 2009

C# Converting from a Hex String to a Color object

So far, we have been looking at Silverlight code examples in XAML. Today, I think it's time to get started with some C# code. The first thing I notice, working with shapes and colours in Silverlight, is that there is no easy way to make a Color class, using a hex String like "#336699".

In Silverlight, you have to instantiate a Color object something like:

Color c = Color.FromArgb(255, 255, 255, 255);

(Which makes a white Color object)

The first value in ARGB is Alpha, which determines the transparency of the colour. 0 is the lowest value, and indicates full transparency, while 255 indicates a fully opaque (non-transparent) Color.

I am used to working with hex Strings though, like "#ffffff", which is a white colour in HTML. There are a few folks who have posted methods for creating Color objects from hex Strings, for example:

Geekpedia
Alex Golesh

I wanted to write a simple method that I could pass a hex String to, that returns a correctly instantiated Color object, something like:

Color c = HexColor("#99ccff");

public Color HexColor(String hex)
{
//remove the # at the front
hex = hex.Replace("#", "");

byte a = 255;
byte r = 255;
byte g = 255;
byte b = 255;

int start = 0;

//handle ARGB strings (8 characters long)
if (hex.Length == 8)
{
a = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
start = 2;
}

//convert RGB characters to bytes
r = byte.Parse(hex.Substring(start, 2), System.Globalization.NumberStyles.HexNumber);
g = byte.Parse(hex.Substring(start+2, 2), System.Globalization.NumberStyles.HexNumber);
b = byte.Parse(hex.Substring(start+4, 2), System.Globalization.NumberStyles.HexNumber);

return Color.FromArgb(a, r, g, b);
}

First, we remove the preceding # character (if there is one), then declare the a, r, g and b bytes that will be used to instantiate the Color object.

Next, we have to handle the two formats the String can appear in, either 8 characters of ARGB "ffffffff", or 6 characters of RGB "ffffff". If the string we have is 8 characters long, we substring the first two characters and do the conversion to a byte value.

From here on, the two strings are substring-ed and parsed in the same manner, although of course the ARGB string will be two positions ahead of the RGB string. This difference is taken care of by the start integer.

Once all of the bytes have been parsed, we use them to instantiate and return a Color object.

10 comments:

  1. I was trying to figure out why hex color codes in WPF themes are coming up with 8 characters, and your blog explained it to me. Thanks.

    BTW you are gorgeous!!

    ReplyDelete
  2. You have no idea how helpful your code has been. I have a blog myself and always appreciate it when folks thank me for my source.

    Baie Dankie!

    ReplyDelete
  3. I will offer one alternate approach that is a little easier way of getting the right color and will also support Colors in #FFF or #FFFFFF formats both equaling white.

    System.Drawing.ColorTranslator.FromHtml("#FFF");

    The result of this method will be a correctly instantiated Color class! HTH

    ReplyDelete
  4. Thank you very much. This saved me a lot of time.

    Beautiful country, South Africa. I was there many years ago and it left a distinct impression.

    ReplyDelete
  5. Yes, the ColorTranslator.FromHtml() method is what you had been looking for so no point in creating a new method!

    ReplyDelete
  6. Also there is the method FromName() which can replace your code completely as well:
    System.Drawing.Color.FromName("#FFCC66")

    ReplyDelete
  7. System.Drawing.ColorTranslator does not exist in Silverlight.
    The original author of this post wrote:

    In Silverlight, you have to instantiate a Color object something like:

    Color c = Color.FromArgb(255, 255, 255, 255);

    This is correct, and that is why he wrote the code to convert a hex string to a color value.

    ReplyDelete