将实际 RGB 值与字典中的 RGB 值进行比较

Compare actual RGB value with RGB values in Dictionary

我有一本字典,里面有两种颜色:

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)

我想根据 RGB 值找出字典中哪种颜色最接近我的颜色imageColour

这是我想出的,但每次我得到所有 3 个 RGB 的 0 值。

//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);
    }

如有任何帮助,我们将不胜感激!

与其编写自己的算法,我认为你应该利用 Linq's ability to sort things using an IComparer

IComparer 是棘手的部分。它的工作是确定一种颜色是 "less than," "equal to," 还是 "greater than" 另一种颜色。对于您的情况,我们将 "greater than" 定义为 "more similar to the reference color."

我已经根据您的代码示例中的比较逻辑编写了一个示例 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,就可以用它来对颜色进行排序了。如果按降序排列,则 "greatest" 颜色(与图像颜色最相似的颜色)将排在列表的第一位。

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();