【问题标题】:Comparing two Bitmaps Issues比较两个位图问题
【发布时间】:2013-12-06 15:57:47
【问题描述】:

我有一个具有位图属性的类。我已经为该对象实现了一个 Equals 覆盖,但我遇到了位图比较问题。这是我所拥有的:

[Serializable]
public class Contact
{
    public string Name { get; set; }
    public Bitmap Photo { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null) { return false; }
        if (obj.GetType() != typeof(Contact)) { return false; }

        Contact compareContact = obj as Contact;

        if (compareContact.FirstName != this.FirstName) { return false; }

        if (compareContact.Photo != null && this.Photo != null)
        {
            if (!compareContact.Photo.IsEqual(this.Photo)) { return false; }
        }
        else
        {
            if (!(compareContact.Photo == null && this.Photo == null)) { return false; }
        }

        return true;
    }
}

public static class BitmapExtensions
{
    public static bool IsEqual(this Bitmap image1, Bitmap image2)
    {
        if (image1 == null || image2 == null)
        {
            return false;
        }

        byte[] image1Bytes =  image1.ToByteArray();
        byte[] image2Bytes =  image2.ToByteArray();

        bool sequenceEqual = image1Bytes.SequenceEqual(image2Bytes);

        return sequenceEqual;
    }

    public static byte[] ToByteArray(this Bitmap image)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            image.Save(ms, ImageFormat.Bmp);
            return ms.ToArray();
        }
    }
}

我的测试:

[TestClass()]
public class vCardTest
{
    private Contact TestContact()
    {
        Contact contact = new Contact();
        contact.Name = "Joe";
        contact.Photo = new System.Drawing.Bitmap(1, 1);
    }

    [TestMethod]
    public void EqualsTest()
    {
        Contact matchedContact  = Common.Copy<Contact >(TestContact);

        Assert.AreEqual<vCard>(vcf, matchedVCard);
    }

还有我的复制方法:

    public static T Copy<T>(T objectToCopy) where T : class
    {
        byte[] serializedObject = objectToCopy.Serialize();
        T copy = serializedObject.Deserialize(typeof(T)) as T;

        return copy;
    }

我的 Equals 函数返回 false。当我查看原始位图和副本的字节数组时,我注意到数组中 58 个字节中有两个字节相差 1。两个字节数组具有相同的长度。

我正在尝试确定序列化和反序列化位图以制作副本是否导致问题或其他原因。

更新

Common.Copy 方法似乎没有导致问题,这个带有字节数组的代码可以成功运行:

    [TestMethod()]
    public void ByteArrayCommonCopyTest()
    {
        byte[] byteArray1 = new byte[] { 0, 1, 1, 0, 123, 45, 56, 0 };
        byte[] byteArray2 = Common.Copy<byte[]>(byteArray1);
        bool expected = true;
        bool actual;

        actual = byteArray1.SequenceEqual(byteArray2);

        Assert.AreEqual(expected, actual);
    }

有趣的是,如果我将 Photo 更新为具有相同大小的新位图,它可以工作:

    [TestMethod]
    public void EqualsTest()
    {
        Contact matchedContact  = Common.Copy<Contact>(TestContact);
        matchedContact.Photo = new System.Drawing.Bitmap(1, 1)

        Assert.AreEqual<vCard>(vcf, matchedVCard);
    }

【问题讨论】:

  • 你的Equals方法中一定有Not all paths returns value编译器错误。
  • 很好,我删除了一些属性以保持示例简单。我在代码中修复了它。

标签: c# .net arrays bitmap


【解决方案1】:

这就是您正在做的事情(我不会这样做) - 您正在将图像流式传输到 bmp 格式的流,然后进行比较。这里的问题是,在内存和 bmp 文件中,您的数据会逐行填充到 4 个字节。可能差异在于填充,在绘图中会被忽略。

相反,您应该编写一个适当的比较器。两个位图是 if:

  • 它们是同一个对象

  • 宽度、高度、分辨率和像素格式匹配
  • 调色板匹配
  • 图像数据完全相同

尺寸很容易检查,应该先做,因为这些测试很便宜。

要比较图像数据,您可以对图像中的每个像素执行GetPixel() 调用,也可以尝试使用LockBits() 直接访问图像数据以获取BitmapData 对象并仅提取一行中的有效字节进行比较。后者是可行的,但代码需要能够正确回答这个问题,“给定一个位图,每行有多少有效字节?”对于任何特定的 PixelFormat。即使那样,您也将把每一行复制到行缓冲区中,然后在其上运行字节数组比较器。也许一旦你开始运行,你可能会对P/Invoke to memcmp 的性能更满意,或者不是使用数组,而是从第一条扫描线 IntPtr 直接进行指针运算,然后执行 memcmp:

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

bool ScanlinesAreTheSame(IntPtr data1, IntPtr data2, int height, long significantBytes, int rowStride)
{
    while (height-- > 0) {
        if (memcmp(data1, data2, significantBytes) != 0) return false;
        data1 = IntPtr.Add(data1, rowStride);
        data2 = IntPtr.Add(data2, rowStride);
    }
    return true;
}

【讨论】:

  • 你知道一个实现图像比较的例子吗?我不想重新发明轮子。
  • Microsoft.VisualStudio.TestTools.UITesting 命名空间下有趣的 ImageCompare 类:msdn.microsoft.com/en-us/library/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2011-08-28
  • 2017-10-31
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多