比较两个颜色列表

10

假设我有两个颜色列表需要进行比较。我有一个用于比较颜色的函数,但我对该函数接收的类型有些困惑。如何转换它们的类型?

public bool AreColorsSimilar(Color c1, Color c2, int tolerance)
{
    return Math.Abs(c1.R - c2.R) < tolerance &&
           Math.Abs(c1.G - c2.G) < tolerance &&
           Math.Abs(c1.B - c2.B) < tolerance;
}

这是我的第一个列表:

public static List<Color> PaletteOfSeasons()
{
    List<Color> springColors = new List<Color>();

    springColors.Add(ColorTranslator.FromHtml("#80a44c"));
    springColors.Add(ColorTranslator.FromHtml("#b4cc3a"));


    return springColors;
}

在另一个列表中,我正在从图像中提取像素:

public static IEnumerable<Color> GetPixels(Bitmap bitmap)
{
    for (int x = 0; x < bitmap.Width; x++)
    {
        for (int y = 0; y < bitmap.Height; y++)
        {
            Color pixel = bitmap.GetPixel(x, y);
            yield return pixel;
        }
    }
}

问题是,我怎样才能比较这些颜色?


1
你想对比的结果想要做什么?你是想要对List进行排序吗?还是想要移除重复项? - Cody Gray
3
旁注:为什么你有一个接收List<Color>参数的方法,该参数会被重新创建然后从方法中返回?它不需要这个参数。 - Tim Schmelter
我想通过将我的静态颜色与任何图像中的颜色进行比较来查找相似的颜色。 - cygnus
@igor1990,所以您想要查看每个像素是否与PaletteOfSeasons中的任何颜色“相似”? - D Stanley
只是提醒一下,Bitmap.GetPixel() 可能会*相对较慢。如果可能的话,您可能需要考虑使用 Bitmap.LockBits() - Scott Chamberlain
显示剩余3条评论
2个回答

2
如果我理解正确:
var springColors = null;
springColors = PaletteOfSeasons(springColors);

var similarColors = GetPixels(bitmap).Intersect(springColors, new ColorComparer(tolerance));

你需要这个类:

public class ColorComparer : IEqualityComparer<Color> 
{
    private _tolerance;

    public ColorComparer(int tolerance)
    {
        _tolerance = tolerance;
    }

    public bool Equals(Color x, Color y)
    {
        return AreColorsSimilar(x, y, _tolerance);
    }

    public int GetHashCode(Foo x)
    {
        return 0;
    }

    private bool AreColorsSimilar(Color c1, Color c2, int tolerance)
    {
        return Math.Abs(c1.R - c2.R) < tolerance &&
           Math.Abs(c1.G - c2.G) < tolerance &&
           Math.Abs(c1.B - c2.B) < tolerance;
    }
}

附言:你的方法PaletteOfSeasons有点令人困惑。愚蠢地将列表传递给方法。

另外,使用Bitmap.LockBits()可以提高代码性能。

最后,这种GetHashCode的实现方式并不好。但在我们的情况下还可以接受。


1
我也考虑过使用IEqualityComparer,但由于GetHashCode存在问题,我没有使用它。你的实现满足了所有需要,但如果在字典中使用它,性能会下降到O(n),这相当糟糕。所以,在我看来,要么实现一个更好的GetHashCode(这很棘手),要么更明确地使用该方法。 - Oliver

0

只需将位图的所有像素与调色板中的所有颜色进行比较:

foreach(var pixel in GetPixels(myBitmap))
{
    foreach(var candidate in paletteOfSeasons)
    {
        if(AreColorsSimilar(pixel, candidate, 42)
        {
            // Hooray, found some similar colors.
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接