2010-01-09 26 views
2

在我的应用程序中,我允许用户构建颜色,然后在以后向他显示颜色的名称或值。如果用户选择红色(全红,不是红色),我想让他看到“红色”。如果他选择一些奇怪的颜色,那么十六进制值就会很好。下面是演示此问题的示例代码:为什么使用Color.FromArgb()创建一个颜色时,Color.IsNamedColor不起作用?

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

From MSDN.

属性值类型:System.Boolean
如果此颜色通过使用 任FROMNAME方法或 的FromKnownColor方法创建的;否则, 错误。

你可以建立一个从所有KnownColor s rgb元组到我想的名字的映射。

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); 
} 
相关问题