Подтвердить что ты не робот

Как получить имя цвета при наличии значения RGB в С#?

Я создаю приложение для поиска наиболее часто используемого цвета изображения, я получаю значение RGB для цвета, но как получить имя цвета, help plz.

4b9b3361

Ответ 1

Как отмечено в комментариях, перечисление KnownColor может использоваться, чтобы сделать это проще:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;

class Test
{
    static void Main()
    {
        Color color = Color.FromArgb(255, 0, 0);
        Console.WriteLine(color.Name); // ffff0000

        var colorLookup = Enum.GetValues(typeof(KnownColor))
               .Cast<KnownColor>()
               .Select(Color.FromKnownColor)
               .ToLookup(c => c.ToArgb());

        // There are some colours with multiple entries...
        foreach (var namedColor in colorLookup[color.ToArgb()])
        {
            Console.WriteLine(namedColor.Name);
        }
    }
}

Оригинальный ответ

Color.FromArgb даст вам Color, но у него никогда не будет названия. Вы должны использовать отражение, чтобы получить названные цвета, насколько я знаю.

Вот еще одна версия решения Коула Кэмпбелла, над которой я работал одновременно...

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;

class Test
{
    static void Main()
    {
        Color color = Color.FromArgb(255, 0, 0);
        Console.WriteLine(color.Name); // ffff0000

        var colorLookup = typeof(Color)
               .GetProperties(BindingFlags.Public | BindingFlags.Static)
               .Select(f => (Color) f.GetValue(null, null))
               .Where(c => c.IsNamedColor)
               .ToLookup(c => c.ToArgb());

        // There are some colours with multiple entries...
        foreach (var namedColor in colorLookup[color.ToArgb()])
        {
            Console.WriteLine(namedColor.Name);
        }
    }
}

Ответ 2

Этот метод использует отражение для проверки предопределенных цветов в классе Color и сравнивает их с цветом, переданным в качестве аргумента. Это может быть оптимизировано дальше, но оно должно дать вам представление об общей технике.

private static String GetColorName(Color color)
{
    var predefined = typeof(Color).GetProperties(BindingFlags.Public | BindingFlags.Static);
    var match = (from p in predefined where ((Color)p.GetValue(null, null)).ToArgb() == color.ToArgb() select (Color)p.GetValue(null, null));
    if (match.Any())
       return match.First().Name;
    return String.Empty;
}

Ответ 3

Вы должны иметь возможность использовать класс Color из пространства имен System.Drawing, он имеет статический метод FromARGB, который возвращает объект Color. Он имеет несколько перегрузок, позволяющих вводить значения RGB следующим образом:

var color = Color.FromArgb(100, 5,5,5).Name;

Ответ 4

Для чего-то быстрого и простого попробуйте это (в WPF):

public string GetNameOfColor(Color color) {
    var colorProperty = typeof(Colors).GetProperties().FirstOrDefault(p =>
        (Color)(p.GetValue(p, null)) == color);
    return (colorProperty != null) ? colorProperty.Name : color.ToString();
}

В Visual Studio 2010 требуется p.GetValue(p, null). В Visual Studio 2013+ вы можете просто использовать p.GetValue(p).

Преимущество этого метода, помимо его краткости, состоит в том, что он не требует ссылок на System.Drawing или System.Reflection, но позволяет пользователю оставаться внутри пространства имен System.Windows, которое является WPF. Для этого требуется ссылка на System.Windows.Media, которую вы, вероятно, уже должны иметь, если работаете с цветами в WPF. Если вы похожи на меня, старайтесь не добавлять System.Drawing в ваши приложения WPF без какой-либо необходимости. Что касается того, почему оставаться внутри пространства имен WPF, это вопрос предпочтения. См. Например обсуждения в WPF v/s System.Drawing.