5

I want to convert a hex color code to the suitable string color name... with the following code I was able to get the hex code of the "most used" color in a photo:

class ColorMath
{
    public static string getDominantColor(Bitmap bmp)
    {
        //Used for tally
        int r = 0;
        int g = 0;
        int b = 0;

        int total = 0;

        for (int x = 0; x < bmp.Width; x++)
        {
            for (int y = 0; y < bmp.Height; y++)
            {
                Color clr = bmp.GetPixel(x, y);

                r += clr.R;
                g += clr.G;
                b += clr.B;

                total++;
            }
        }

        //Calculate average
        r /= total;
        g /= total;
        b /= total;

        Color myColor = Color.FromArgb(r, g, b);
        string hex = myColor.R.ToString("X2") + myColor.G.ToString("X2") + myColor.B.ToString("X2");

        return hex;
    }
}

So I want for a hex code like: #3A322B to appear something like "dark brown"

10
  • 2
    How do you plan on doing this for every possible colour combination? Commented Nov 30, 2016 at 12:41
  • 1
    stackoverflow.com/questions/2109756/… try this. and your question is not clear. can you explain clearly? Commented Nov 30, 2016 at 12:43
  • I want to add some codes and refer them to a single color like if he sees something like #ff0000 or anything similar to instantly show "Red". Commented Nov 30, 2016 at 12:44
  • 2
    What do you expect to get for one of colors which is not a part of Colors ? Otherwise a simple enumerating and check versus RGB values shouldn't be hard... Note, this is for WPF. Commented Nov 30, 2016 at 12:44
  • 3
    Just add return "dark brown"; ;-) No, seriously, on a color photograph blending all colors like your algorithm does, always will result in something like brown – the "average" color is something different than the dominant color; you probably want an algorithm like this one: github.com/lokesh/color-thief which quantizes colors using a median cut algorithm. See a demo here: lokeshdhakar.com/projects/color-thief Commented Nov 30, 2016 at 12:57

1 Answer 1

3

Assuming the colour is in the KnownColor enum you can use ToKnownColor:

KnownColor knownColor = color.ToKnownColor();

To note is the following from the MSDN docs:

When the ToKnownColor method is applied to a Color structure that is created by using the FromArgb method, ToKnownColor returns 0, even if the ARGB value matches the ARGB value of a predefined color.

So to get your colour you could use something like the following from the hex code:

Color color = (Color)new ColorConverter().ConvertFromString(htmlString);

Where htmlString is in the form #RRGGBB.

To convert KnownColor to a string simply use ToString on the enum (see here):

string name = knownColor.ToString();

Putting all of that together you can use this method:

string GetColourName(string htmlString)
{
    Color color = (Color)new ColorConverter().ConvertFromString(htmlString);
    KnownColor knownColor = color.ToKnownColor();

    string name = knownColor.ToString();
    return name.Equals("0") ? "Unknown" : name;
}

Calling it like:

string name = GetColourName("#00FF00");

Results in Lime.

I have also found an answer to a similar question that seems to work quite well too which uses reflection and falls back to html colour names:

string GetColorName(Color color)
{
    var colorProperties = typeof(Color).GetProperties(BindingFlags.Public | BindingFlags.Static)
                                       .Where(p => p.PropertyType == typeof(Color));
    foreach (var colorProperty in colorProperties) 
    {
        var colorPropertyValue = (Color)colorProperty.GetValue(null, null);
        if (colorPropertyValue.R == color.R  && colorPropertyValue.G == color.G 
         && colorPropertyValue.B == color.B)
        {
            return colorPropertyValue.Name;
        }
    }

    //If unknown color, fallback to the hex value
    //(or you could return null, "Unkown" or whatever you want)
    return ColorTranslator.ToHtml(color);
}
Sign up to request clarification or add additional context in comments.

5 Comments

Yeah it works now but there are so many unknown colors like: (All the following didn't work) #171B16 #9F806D #584A45 #070603 And in the real life they look kind of obvious
@C.Cretan I advise you to read the MSDN docs I linked to about the KnownColor enum it tells you all the values it has. However the first example you linked to doesn't have a name even when I google it so I don't know what you expect to happen there
@C.Cretan Regarding the edit to your comment, just because they look like a colour does not mean they are that colour. For example #EF0000 looks almost the same as Red (#FF0000) but it isn't.
@C.Cretan If my answer helped you find an answer to the main question, could you mark it as accepted so that others can find an answer to the question easier?
Is there also a version of this that gets the HUE name instead of the color name?