Wednesday, October 10, 2007

Color.FromArgb(r, g, b).ToKnownColor()

I was going through the code of CSAH when I came across the class HtmlColor.  It does a mapping of r, g, b colors to a name by doing this:

this.color = String.Format("#{0:x2}{1:x2}{2:x2}", r, g, b);
switch (this.color)
{
    case "#00ffff":
        this.color = "aqua";
        break;
    case "#000000":
        this.color = "black";
        break;
        // more code

 

I tried this:

Enum.GetName(typeof(KnownColor), Color.FromArgb(255, r, g, b).ToKnownColor());

 

Nope.. didn't work!  ToKnownColor() was returning zero.  A quick lookup in MSDN Documentation proved my worst fears.  Unless you create a Color FromName, ToKnownColor() will return zero!

I googled and found this solution.  Here's my improved(?) version:

Dictionary<int, string> colorCache = new Dictionary<int, string>();
public string GetKnownColorName(int r, int g, int b)
{
    int iArgb = Color.FromArgb(r, g, b).ToArgb();
 
    if (this.colorCache.ContainsKey(iArgb)) 
        return this.colorCache[iArgb];
 
    string namedColor = null;
    foreach (string name in Enum.GetNames(typeof(KnownColor)))
    {
        Color kc = Color.FromName(name);
        if (!kc.IsSystemColor && kc.ToArgb() == iArgb)
        {
            namedColor = kc.Name;
            this.colorCache.Add(iArgb, namedColor);
            break;
        }
    }
 
    return namedColor;
}
 
Technorati Tags: ,

3 comments:

Andrew Larkin said...

Thanks. Been hunting high and low for something like this!

Andy

Anonymous said...

Hey,

thanks a lot... I just started to write my own method. than I found that article.

Works fine

Anonymous said...

Very nice. Most appreciated