将十六进制颜色代码转换为颜色名称(字符串)

5
我希望将十六进制颜色代码转换为适当的字符串颜色名称……使用以下代码,我能够获取照片中“最常用”的颜色的十六进制代码:
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;
    }
}

我想要像 #3A322B 这样的十六进制代码翻译成 "深棕色"。

2
你打算如何为每种可能的颜色组合做到这一点? - Alfie Goodacre
1
尝试这个。你的问题不清楚。你能解释清楚吗? - user6730095
我想添加一些代码并将它们引用到单个颜色,例如如果他看到类似于#ff0000或任何类似的东西,立即显示“红色”。 - user7140850
2
你期望从不属于Colors的颜色中获得什么?否则,简单地枚举并检查RGB值不应该很难...注意,这是针对WPF的。 - Sinatr
3
只需添加 return "dark brown"; ;-) 不过,说真的,在彩色照片中像您的算法一样混合所有颜色,总会导致类似棕色的颜色 - “平均”颜色与主导颜色不同。 您可能需要像此算法一样的算法:https://github.com/lokesh/color-thief,该算法使用中位切割算法对颜色进行量化处理。 在此处查看演示:http://lokeshdhakar.com/projects/color-thief - Dirk Vollmar
显示剩余5条评论
1个回答

3

假设颜色在KnownColor枚举中,您可以使用ToKnownColor

KnownColor knownColor = color.ToKnownColor();

以下来自 MSDN 文档的需要注意的事项:
当对使用 FromArgb 方法创建的 Color 结构应用 ToKnownColor 方法时,即使 ARGB 值与预定义颜色的 ARGB 值匹配,ToKnownColor 也会返回 0。
因此,为了获取您的颜色,您可以使用以下类似于十六进制代码的内容:
Color color = (Color)new ColorConverter().ConvertFromString(htmlString);

htmlString#RRGGBB 的形式存在时。

要将 KnownColor 转换为字符串,只需在枚举上使用 ToString 方法(参见此处):

string name = knownColor.ToString();

把所有东西放在一起,您可以使用以下方法:
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;
}

调用方式:

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

使用Lime可以得到以下结果。

我还找到了一篇答案,该答案使用反射并回退到HTML颜色名称,对于类似问题似乎也很有效。

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);
}

是的,现在它可以工作了,但有很多未知的颜色,比如: (以下所有内容都不起作用) #171B16 #9F806D #584A45 #070603 而在现实生活中,它们看起来似乎很明显。 - user7140850
@C.Cretan 我建议你阅读我提供的有关 KnownColor 枚举的 MSDN 文档,它会告诉你所有可能的值。然而,你提供的第一个示例即使在我谷歌搜索时也没有名称,所以我不知道你希望发生什么。 - TheLethalCoder
关于您评论的编辑,仅仅因为它们看起来像颜色并不意味着它们就是那种颜色。例如,#EF0000 看起来几乎和红色 (#FF0000) 一样,但实际上并不是。 - TheLethalCoder
1
@C.Cretan 如果我的回答帮助您找到了主要问题的答案,您能否将其标记为已接受,以便其他人更容易地找到问题的答案? - TheLethalCoder
这个程序有没有一个版本可以获取HUE名称,而不是颜色名称? - A.bakker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接