我想逐字节比较两个图像。它们都是8位BMP图像,大小正好是40000字节。第一个图像在内存中生成为一个字节数组,第二个图像从文件读取到Image对象。
我使用MemoryStream
个实例进行比较:
byte[] generatedImage = new byte[40000];
// some unrelated logic of image generation ...
MemoryStream imageStream1 = new MemoryStream(generatedImage);
// loaded image, 200x200 bmp - 40000 bytes
MemoryStream imageStream2 = new MemoryStream();
Image loadedImage = Image.FromFile("image.bmp");
loadedImage.Save(imageStream2, ImageFormat.Bmp);
问题是加载的图像imageStream2
的内存流包含 more 而不是40000字节,据我所知,它包含有关BMP本身的一些信息。因此创建第二个流时Length
等于41078,Position
等于1278.我会理解Position
是否为1078,但它不是,并且从位置开始剩下不到40000字节。
在我的算法中,我需要尽可能快地比较图像,所以我拒绝了创建位图和通过GetPixel
方法进行比较的想法。我使用MemoryStream.ReadByte
方法进行比较。
如何从第二个Stream
获得“真正的”BMP字节?在这种情况下,有没有办法在逐字节的基础上比较图像?
答案 0 :(得分:3)
这是一篇关于在C#中快速比较图像的帖子。它从一个非常慢的版本开始(仍然比GetPixel更好),最终得到的速度是其快25倍的版本:
http://danbystrom.se/2008/12/14/improving-performance/
如果图像相同,则返回一个零的数字,返回值越高 - 它们的差异越大。它应该指向正确的方向。
但是,有一点需要注意。它经过优化,仅适用于32bpp图像。如果您有24bpp图像(默认情况下加载后是.jpg),您需要更多“复杂”代码或者只需将其转换为32bpp。 “复杂性”是你不能在一个循环中进行所有比较,而是逐行循环并逐个比较每一行。答案 1 :(得分:2)
http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header
在偏移量10处读取4个字节以获得像素数据的偏移量。在偏移量2处读取4个字节以获得包括标题在内的整个事物的大小。从后者中减去前者以获得像素数据的大小。
答案 2 :(得分:0)
我不会在字节级别上比较它们。相反,我会将它们放入Bitmap
。并使用从零到GetPixel(x,y)
或Width
的所有可能值调用Height
来迭代所有像素。
答案 3 :(得分:0)
逐字节比较图像不是解决问题的好方法。在这种情况下,您可以使用其中一种哈希算法的实现。
“Hash Function”获取可变长度的值并生成具有恒定长度的输出。例如,SHA256算法获取输入值并生成256位输出。请注意,当且仅当相应的数据匹配且数据中的任何微小变化导致哈希值发生显着变化时,两组数据的哈希才相同,因此在比较大量数据时这是一种很酷的方法。有关更多信息,请阅读本文的“Flash中的哈希”部分: http://www.codeproject.com/KB/GDI-plus/comparingimages.aspx?msg=3503625&display=Mobile