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"

TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
  • 2
    How do you plan on doing this for every possible colour combination? – Alfie Goodacre Nov 30 '16 at 12:41
  • 1
    http://stackoverflow.com/questions/2109756/how-to-get-color-from-hexadecimal-color-code-using-net try this. and your question is not clear. can you explain clearly? – user6730095 Nov 30 '16 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". –  Nov 30 '16 at 12:44
  • You could match the hex code against the code for the predefined colours, but it won't work if your calculated value isn't one of those. – ChrisF Nov 30 '16 at 12:44
  • 2
    What do you expect to get for one of colors which is not a part of [Colors](https://msdn.microsoft.com/en-us/library/system.windows.media.colors(v=vs.110).aspx) ? Otherwise a simple enumerating and check versus RGB values shouldn't be hard... Note, this is for WPF. – Sinatr Nov 30 '16 at 12:44
  • "unknown color" and I would like to let the user add the "Unknown Color" and say the name of it –  Nov 30 '16 at 12:45
  • Possible duplicate of [convert hex code to color name](http://stackoverflow.com/questions/7791710/convert-hex-code-to-color-name) (that's for winforms). – Sinatr Nov 30 '16 at 12:50
  • 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: https://github.com/lokesh/color-thief which quantizes colors using a median cut algorithm. See a demo here: http://lokeshdhakar.com/projects/color-thief – Dirk Vollmar Nov 30 '16 at 12:57
  • yeah That's true but I want it in c# –  Nov 30 '16 at 13:21
  • I find the suitable form in c# but looks so complicated and I don't know if it's free to use? –  Nov 30 '16 at 13:27

1 Answers1

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);
}
Community
  • 1
  • 1
TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
  • 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 –  Nov 30 '16 at 13:17
  • @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 – TheLethalCoder Nov 30 '16 at 13:20
  • @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. – TheLethalCoder Nov 30 '16 at 13:24
  • 1
    @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? – TheLethalCoder Nov 30 '16 at 14:20
  • Is there also a version of this that gets the HUE name instead of the color name? – A.bakker Nov 22 '20 at 20:36