Сравните фактическое значение RGB со значениями RGB в словаре - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть словарь с двумя цветами:

private Dictionary<string, Color> someColours = new Dictionary<string, Color>()
    {
        {"red", Color.FromArgb(255,0,0) },
        { "purple",Color.FromArgb(100,100,100) }
    };

, и у меня есть переменная Color imageColour, которая представляет значения RGB (100,100,100)

Я хотел бы узнатькакой цвет в словаре является самым близким к моему цвету imageColour на основе значений RGB.

Вот то, что я придумал, но каждый раз, когда я получаю 0 значений для всех 3 RGB.

//Compare values
    public Color CompareColours()
    {
        var imageColour = AverageColour();

        int a = 0;
        int c = 0;
        int d = 0;

        //check if Dictionary contains 'Color' type value

        if (someColours.OfType<Color>().Any())
         {  //Loop over dictionary
            foreach (var setColors in someColours.Values)
            { //Compare both values
              if(setColors.ToArgb().Equals(imageColour.ToArgb()))
                {
                    Color testColr = setColors;
                    a = a + testColr.R;
                    c += testColr.G;
                    d += testColr.B;
                }
            }
         }
        return Color.FromArgb(a, c, d);
    }

Любая помощь будет высоко ценится!

1 Ответ

0 голосов
/ 11 февраля 2019

Вместо того, чтобы писать собственный алгоритм, я думаю, вам следует воспользоваться способностью Linq сортировать вещи, используя IComparer

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

Я написал пример IComparer на основе логики сравнения в вашем примере кода.Я не уверен, что этот компаратор даст ожидаемые вами результаты - если нет, просто измените его в соответствии с вашими потребностями.

class ColorDistanceComparer : IComparer<Color>
{
    readonly int referenceColor;

    public ColorDistanceComparer(Color referenceColor)
        => this.referenceColor = referenceColor.ToArgb();

    public int Compare(Color x, Color y)
        => Math.Abs(referenceColor - y.ToArgb()) - Math.Abs(referenceColor - x.ToArgb());
}

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

var bestMatch = _referenceColours
    .OrderByDescending(kvp => kvp.Value, new ColorDistanceComparer(imageColour))
    .Select(kvp => kvp.Key) // Select kvp.Value if you want the Color rather than its name
    .First();
...