Почему Color.IsNamedColor не работает, когда я создаю цвет с помощью Color.FromArgb ()? - PullRequest
2 голосов
/ 09 января 2010

В моем приложении я разрешаю пользователю создать цвет, а затем покажу ему имя или значение цвета. Если пользователь выбирает красный (полностью красный, а не красный), я хочу показать ему «красный». Если он выберет какой-то странный цвет, тогда значение шестнадцатеричного кода будет просто нормальным. Вот пример кода, который демонстрирует проблему:

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 никогда не возвращает истину. Глядя на значения ARGB для моего цвета и Color.Red, я не вижу разницы. Однако вызов Color.Red.GetHashCode() возвращает хэш-код, отличный от Color.FromArgb(255, 0, 0).GetHashCode().

Как я могу создать цвет, используя заданные пользователем значения RGB, и свойство Name должно быть правильным?

Ответы [ 2 ]

2 голосов
/ 09 января 2010

Из MSDN.

Тип значения свойства: System.Boolean
истина, если этот цвет был создан используя либо метод FromName, либо метод FromKnownColor; иначе, ложь.

Вы можете построить карту из всех KnownColor s rgb-кортежей для имен, которые я полагаю.

0 голосов
/ 09 января 2010

Вероятно, это не самый быстрый метод, но он работает. Цвета не обязательно должны точно соответствовать названию, например. 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);
}
...