C#引用比较

4

当您尝试比较两个 System.Drawing.Image 实体时,可能会出现什么问题?

我有一些使用 Image.FromFile(path) 方法迭代构建的 IEnumerable<Image> images

但是以下代码产生了我无法理解的结果:

foreach (var image1 in images)
{
    foreach (var image2 in images)
    {
        if (image1 == image2)
        {
            // (Do something!)
        }
    }
}

问题在于(Do something!)部分从未被调用。
调试器显示图像对象有一个名为nativeImage的属性,我猜测这是一个原始内存指针,因为System.Drawing.Image使用了封送实现。
这个内存指针一直在变化,我猜想这里发生了某种克隆,但我不知道该做什么。 我做错了什么,如何比较从一个IEnumerable<>序列中获取的System.Drawing.Image对象是否相同? 谢谢。

更新

        var paths = new List<String> {"Tests/1_1.jpg", "Tests/1_2.jpg"};
        IEnumerable<Image> images = paths.Select(path => Image.FromFile(path)).ToList();

        foreach (var image1 in images)
        {
            foreach (var image2 in images)
            {
                if (ReferenceEquals(image1, image2))
                {
                    
                }
            }
        }
< p > < em > < strong > 没有使用 < code > ToList() ,很明显这不起作用,我非常愚蠢。 < / strong > < / em > < / p > < p > 感谢大家。 < / p >

你正在比较的图片中,是否有任何一张实际上是相同的图片? - gideon
@giddy 是的,我检查了两个尺寸不同的图像。显然,它们指向相同的图像,但被视为不同的对象。 - Yippie-Ki-Yay
有趣...我刚刚完成了这个练习, //(Do Something!) 这行代码在列表中的每个图像上都被触发了一次。我所做的只是加载了一系列 PNG 图像。 - RQDQ
2个回答

2

请记住,每次调用GetEnumerator时,每次调用MoveNext都会返回新的对象。您需要做的是将迭代强制转换为列表。

var imageList = images.ToList();

是的,那就是我搞砸了。非常感谢你) - Yippie-Ki-Yay

1

通过 image1 == image2,你只是在比较图像的引用(而不是逐像素比较图像)。

通过调用 Image.FromFile(path),每次调用此方法都会创建新的图像对象(即使路径相同),因此它们始终具有不同的引用。

我不知道是否有一种方法可以逐像素比较图像,但是你当然可以为此实现自己的机制(这看起来并不困难)。


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