我可以比较两个相同大小的位图以确定它们是否相同的最快方法是什么? [英] What is the fastest way I can compare two equal-size bitmaps to determine whether they are identical?

查看:20
本文介绍了我可以比较两个相同大小的位图以确定它们是否相同的最快方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个函数来确定两个大小相等的位图是否相同.我现在拥有的函数只是一次比较每个位图中的一个像素,在第一个不相等的像素处返回 false.

I am trying to write a function to determine whether two equal-size bitmaps are identical or not. The function I have right now simply compares a pixel at a time in each bitmap, returning false at the first non-equal pixel.

虽然这很有效,并且适用于小位图,但在生产中,我将在紧密循环和较大的图像上使用它,所以我需要一个更好的方法.有人有什么建议吗?

While this works, and works well for small bitmaps, in production I'm going to be using this in a tight loop and on larger images, so I need a better way. Does anyone have any recommendations?

顺便说一下,我使用的语言是 C# - 是的,我已经在使用 .LockBits 方法.=)

The language I'm using is C# by the way - and yes, I am already using the .LockBits method. =)

编辑:我已经对给出的一些建议的实现进行了编码,这里是基准测试.设置:两个相同(最坏情况)位图,大小为 100x100,每个都有 10,000 次迭代.结果如下:

Edit: I've coded up implementations of some of the suggestions given, and here are the benchmarks. The setup: two identical (worst-case) bitmaps, 100x100 in size, with 10,000 iterations each. Here are the results:

CompareByInts (Marc Gravell) :   1107ms
CompareByMD5  (Skilldrick)   :   4222ms
CompareByMask (GrayWizardX)  :    949ms

在 CompareByInts 和 CompareByMask 中,我使用指针直接访问内存;在 MD5 方法中,我使用 Marshal.Copy 来检索字节数组并将其作为参数传递给 MD5.ComputeHash.CompareByMask 只是稍微快一点,但考虑到上下文,我认为任何改进都是有用的.

In CompareByInts and CompareByMask I'm using pointers to access the memory directly; in the MD5 method I'm using Marshal.Copy to retrieve a byte array and pass that as an argument to MD5.ComputeHash. CompareByMask is only slightly faster, but given the context I think any improvement is useful.

谢谢大家.=)

编辑 2:忘记打开优化 - 这样做可以让 GrayWizardX 的回答更有力:

Edit 2: Forgot to turn optimizations on - doing that gives GrayWizardX's answer even more of a boost:

CompareByInts   (Marc Gravell) :    944ms
CompareByMD5    (Skilldrick)   :   4275ms
CompareByMask   (GrayWizardX)  :    630ms
CompareByMemCmp (Erik)         :    105ms

有趣的是,MD5 方法根本没有改进.

Interesting that the MD5 method didn't improve at all.

编辑 3:发布了我的答案 (MemCmp),这让其他方法大吃一惊.o.O

Edit 3: Posted my answer (MemCmp) which blew the other methods out of the water. o.O

推荐答案

Edit 8-31-12: per Joey's下面的评论,请注意您比较的位图的格式.它们可能包含使位图不相等的步幅上的填充,尽管在像素方面是等效的.有关详细信息,请参阅此问题.

Edit 8-31-12: per Joey's comment below, be mindful of the format of the bitmaps you compare. They may contain padding on the strides that render the bitmaps unequal, despite being equivalent pixel-wise. See this question for more details.

阅读这个答案关于比较字节的问题arrays 产生了一个更快的方法:在 msvcrt 中使用 P/Invoke 和 memcmp API 调用.代码如下:

Reading this answer to a question regarding comparing byte arrays has yielded a MUCH FASTER method: using P/Invoke and the memcmp API call in msvcrt. Here's the code:

[DllImport("msvcrt.dll")]
private static extern int memcmp(IntPtr b1, IntPtr b2, long count);

public static bool CompareMemCmp(Bitmap b1, Bitmap b2)
{
    if ((b1 == null) != (b2 == null)) return false;
    if (b1.Size != b2.Size) return false;

    var bd1 = b1.LockBits(new Rectangle(new Point(0, 0), b1.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    var bd2 = b2.LockBits(new Rectangle(new Point(0, 0), b2.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

    try
    {
        IntPtr bd1scan0 = bd1.Scan0;
        IntPtr bd2scan0 = bd2.Scan0;

        int stride = bd1.Stride;
        int len = stride * b1.Height;

        return memcmp(bd1scan0, bd2scan0, len) == 0;
    }
    finally
    {
        b1.UnlockBits(bd1);
        b2.UnlockBits(bd2);
    }
}

这篇关于我可以比较两个相同大小的位图以确定它们是否相同的最快方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆