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

发布于 2024-08-17 10:27:08 字数 686 浏览 3 评论 0原文

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

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 属性正确显示?

In my app I allow the user to build a color, and then show him the name or value of the color later on. If the user picks red (full red, not red-ish), I want to show him "red". If he picks some strange color, then the hex value would be just fine. Here's sample code that demonstrates the problem:

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

Even with very obvious colors like red IsNamedColor never returns true. Looking at the ARGB values for my color and Color.Red, I see no difference. However, calling Color.Red.GetHashCode() returns a different hash code than Color.FromArgb(255, 0, 0).GetHashCode().

How can I create a color using user specified RGB values and have the Name property come out right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花心好男孩 2024-08-24 10:27:08

来自 MSDN。

属性值类型:System.Boolean
如果此 Color 是由以下人员创建的,则为 true
使用 FromName 方法或
FromKnownColor 方法;否则,
错误。

您可以从所有 KnownColors rgb 元组到我认为的名称构建一个映射。

From MSDN.

Property Value Type: System.Boolean
true if this Color was created by
using either the FromName method or
the FromKnownColor method; otherwise,
false.

You could build a map from all KnownColors rgb tuples to names I suppose.

喜爱纠缠 2024-08-24 10:27:08

这可能不是最快的方法,但它确实有效。颜色不必与要选择的名称完全匹配,例如 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);
}

This probably isn't the fastest method, but it does work. Colors don't have to match exactly for the name to be chosen e.g. GetColorName(Color.FromArgb(254, 254, 0)); will still return Yellow.

I've deliberately left out access modifiers

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文