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

13

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

  • 2
    Может быть, это поможет, stackoverflow.com/questions/365935/…
  • 0
    Что вы пробовали ? Где ты застрял? Что вы ожидаете, когда цвет не является одним из известных именованных?
Теги:

4 ответа

20

Как отмечено в комментариях, 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(KnownValue))
               .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, но у него никогда не будет имени. Насколько мне известно, вам нужно использовать отражение, чтобы получить названные цвета.

Вот еще одна версия решения Cole Campbell, над которой я работал одновременно...

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);
        }
    }
}
  • 0
    Вы можете использовать перечисление KnownColor, чтобы избежать повторного выбора.
  • 0
    @AndrewMorton: AndrewMorton: Хороший вопрос - отредактировано.
Показать ещё 2 комментария
11

Этот метод использует отражение для проверки предопределенных цветов в классе 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;
}
  • 0
    Вместо Any затем First вызовите FirstOrDefault затем проверьте, является ли результат нулевым.
  • 2
    Цвет - это структура. FirstOrDefault вернет пустой цвет, а не нуль.
2

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

var color = Color.FromArgb(100, 5,5,5).Name;
  • 0
    Из документации: This method returns either the user-defined name of the color, if the color was created from a name, or the name of the known color. For custom colors, the RGB value is returned.
  • 3
    Это не возвращает имя в форме «красный». Для вашего примера название выходит как 64050505.
Показать ещё 2 комментария
0

Для чего-то быстрого и простого попробуйте это (в 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.

  • 0
    Как это отличается от двух других ответов, и какой частью является WPF?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню