【问题标题】:c# memcmp image compare errorc# memcmp 图像比较错误
【发布时间】:2015-07-23 13:33:51
【问题描述】:

我正在尝试使用 memcmp 方法比较 2 个小图像块。 我看到了这个答案What is the fastest way I can compare two equal-size bitmaps to determine whether they are identical? 我试图在我的项目中实现这一点:

private void Form1_Load(object sender, EventArgs e)
{
    Bitmap prev, curr;

    prev = (Bitmap) Image.FromFile(@"C:\Users\Public\Desktop\b.png");



    curr = (Bitmap)Image.FromFile(@"C:\Users\Public\Desktop\b.png");
    MessageBox.Show(CompareMemCmp(prev, curr).ToString());
}

这是方法-

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

我在调用memcmp 函数时遇到此错误

A call to PInvoke function 'WindowsFormsApplication1!WindowsFormsApplication1.Form1::memcmp' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

知道为什么会这样吗?我都是根据那个答案做的。

【问题讨论】:

    标签: c# compare memcmp


    【解决方案1】:

    正确的签名是:

    [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
    static extern int memcmp(IntPtr b1, IntPtr b2, IntPtr count);
    

    因为在 C 中,countsize_t,所以它可以是 32 位或 64 位,具体取决于程序是以 32 位还是 64 位运行。

    然后使用它:

    return memcmp(bd1scan0, bd2scan0, (IntPtr)len) == 0;
    

    【讨论】:

    • 等等!但是 bd1scan0 和 bd2scan0 是 Intptr !我不想比较字节数组! @xanatos
    • @itapi 有各种正确的签名...在一个修订版中,我从一个更改为另一个...恢复了您在开始时看到的那个。请注意,我添加了CallingConvention=CallingConvention.Cdecl)]
    • 好的,谢谢你。最后一个问题,一点咨询——我创建了一个屏幕共享应用程序,我只想通过套接字发送差异部分,以使其更快、更高效。将屏幕截图分成小块是否是个好主意,使用这种方法比较每个块,并且只有在有变化的情况下才发送?因为实际上这种方法确实表明了变化 - 我的意思是变化有多大,如果有一个小的或巨大的变化。非常感谢你的帮助:) @xanatos
    • @itapi 你不能那样做......LockBits 并没有真正给你“漂亮”的图像矩形裁剪。请参阅stackoverflow.com/q/10771300/613130 了解它的作用。我要做的是(例如)两个图像的二进制差异,然后用DeflateStream 压缩它。相等的字节将被区分为 0,而 0 的长序列将被DeflateStream“删除​​”
    • @itapi 使用二进制差异我的意思是你创建一个byte[] diff = new byte[len],然后你把for (int i = 0; i < len; i++) diff[i] = Marshal.ReadByte(bd1scan0, i) - Marshal.ReadByte(bd2scan0, i)放在那里
    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 2011-12-18
    • 2012-07-25
    • 1970-01-01
    相关资源
    最近更新 更多