当我使用Color.FromArgb()创建颜色时,为什么Color.IsNamedColor不起作用?

时间:2010-01-09 04:57:04

标签: c# .net colors system.drawing.color

在我的应用程序中,我允许用户构建颜色,然后稍后向他显示颜色的名称或值。如果用户选择红色(全红色,而不是红色),我想向他显示“红色”。如果他选择一些奇怪的颜色,那么十六进制值就可以了。以下是演示此问题的示例代码:

static string GetName(int r, int g, int b)
{
    Color c = Color.FromArgb(r, g, b);  // Note that specifying a = 255 doesn't make a difference
    if (c.IsNamedColor)
    {
        return c.Name;
    }
    else
    {
        // return hex value
    }
}

即使是非常明显的颜色,如红色IsNamedColor也永远不会返回true。查看我的颜色和Color.Red的ARGB值,我认为没有区别。但是,调用Color.Red.GetHashCode()会返回与Color.FromArgb(255, 0, 0).GetHashCode()不同的哈希码。

如何使用用户指定的RGB值创建颜色并使Name属性正确?

2 个答案:

答案 0 :(得分:2)

From MSDN.

  

属性值类型:System.Boolean
  如果此颜色是由创建的,则为true   使用FromName方法或   FromKnownColor方法;除此以外,   假的。

您可以从所有KnownColor s rgb元组构建一个映射到我想要的名称。

答案 1 :(得分:0)

这可能不是最快的方法,但确实有效。颜色不必与要选择的名称完全匹配,例如GetColorName(Color.FromArgb(254, 254, 0));仍会返回黄色。

我故意遗漏了访问修饰符

Color[] KnownColors; 

void Init (){
    KnownColors = (from colorInfo in typeof(Color).GetProperties(BindingFlags.Static | BindingFlags.CreateInstance |BindingFlags.Public)
                   where colorInfo.PropertyType == typeof (Color)
                   select (Color)colorInfo.GetValue(null, null)).Where (c => c.A != 0).ToArray();
}

string GetColorName(Color inColour)
{

    // I'm just getting started on LINQ so im not
    // sure how to do this with it (Maybe some one can help out with that)

    int MinDistance = int.MaxValue;

    Color closestKnown = Color.Black;
    foreach (var c in KnownColors)
    {
        var d = ColorDistance(c, inColour);

        if (d < MinDistance){
            closestKnown = c;
            MinDistance = d;
        }
    }

    return closestKnown.Name;
}


int ColorDistance(Color c1, Color c2)
    {

    var ad = (c1.A - c2.A);
    var rd = (c1.R - c2.R);
    var gd = (c1.G - c2.G);
    var bd = (c1.B - c2.B);

    return (ad * ad) + (rd * rd) + (gd * gd) + (bd * bd);
}