2010-08-02 104 views

回答

12

您可以使用一组称为TestApi的工具,它是一个开源库,用于帮助单元测试。一个这样的API被称为Visual Verification API,这不正是你所需要的 - 它可以比较两个图像,并告诉你,如果他们是平等的:

// 1. Capture the actual pixels from a given window 
Snapshot actual = Snapshot.FromRectangle(new Rectangle(0, 0, 100, 100)); 

// 2. Load the reference/master data from a previously saved file 
Snapshot expected = Snapshot.FromFile("Expected.png")); 

// 3. Compare the actual image with the master image 
// This operation creates a difference image. Any regions which are identical in 
// the actual and master images appear as black. Areas with significant 
// differences are shown in other colors. 
Snapshot difference = actual.CompareTo(expected); 

// 4. Configure the snapshot verifier - It expects a black image with zero tolerances 
SnapshotVerifier v = new SnapshotColorVerifier(Color.Black, new ColorDifference()); 

// 5. Evaluate the difference image 
if (v.Verify(difference) == VerificationResult.Fail) 
{ 
    // Log failure, and save the diff file for investigation 
    actual.ToFile("Actual.png", ImageFormat.Png); 
    difference.ToFile("Difference.png", ImageFormat.Png); 
} 
4

最简单的地方就是尺寸。如果尺寸不相等,您可以将其声明为false。

如果您需要逐像素地浏览它们,则需要两个for循环。沿着这些路线的东西:

Bitmap ImageA... 
Bitmap ImageB... 

for (Int64 x = 0; x < ImageA.Width; x++) 
{ 
    for (Int64 y = 0; y < ImageA.Height; y++) 
    { 
     if (ImageA.GetPixel(x, y) != ImageB.GetPixel(x, y)) 
     { 
      return false; 
     } 
    } 
} 

这是伪代码(在C#中存在的功能,虽然我不能在此刻想起他们)和非常简单的,但是你要如何执行基本像素对像素检查。

但是,请注意,对于该工作循环,图像必须具有相同的尺寸。如果他们不是,那么如果您尝试在较小区域外采样像素,则可能会遇到例外情况。它也不会非常快速地比较像素,因此您可能希望先找到另一种丢弃可能重复的方法。

编辑:我不知道如何在Image上做到这一点,但它对于Bitmap很简单。没有一种可见的方式将图像像素数据从课堂中取出。看起来Bitmaps继承自Images,所以这可能仍然有效。鉴于图像是Bitmaps和图元文件的抽象类,它们可能没有简单的内部像素列表。

+4

所以,我只想提的是,如果两个图像是比较大的,这将是缓慢的一只狗。我会使用Lockbits,并且通过行而不是列循环,因为它将如何在内存中进行排列。 – 2010-08-02 05:31:34

1

我有同样的问题,这一天,我的解决办法是采取image1和image2转换为256x256或128x128都翻译后,然后生成一个image3与他们之间的差异,然后扫描image3检查差异和返回差异量,我发现,LOWER差异数量%更相等图像是和更多他们可能是平等的。这样,即使图像大小不同,也可以识别图像是否相同。这里是代码。

double CompareImages(Bitmap InputImage1, Bitmap InputImage2, int Tollerance) 
    { 
     Bitmap Image1 = new Bitmap(InputImage1, new Size(128, 128)); 
     Bitmap Image2 = new Bitmap(InputImage2, new Size(128, 128)); 
     int Image1Size = Image1.Width * Image1.Height; 
     int Image2Size = Image2.Width * Image2.Height; 
     Bitmap Image3; 
     if (Image1Size > Image2Size) 
     { 
      Image1 = new Bitmap(Image1, Image2.Size); 
      Image3 = new Bitmap(Image2.Width, Image2.Height); 
     } 
     else 
     { 
      Image1 = new Bitmap(Image1, Image2.Size); 
      Image3 = new Bitmap(Image2.Width, Image2.Height); 
     } 
     for (int x = 0; x < Image1.Width; x++) 
     { 
      for (int y = 0; y < Image1.Height; y++) 
      { 
       Color Color1 = Image1.GetPixel(x, y); 
       Color Color2 = Image2.GetPixel(x, y); 
       int r = Color1.R > Color2.R ? Color1.R - Color2.R : Color2.R - Color1.R; 
       int g = Color1.G > Color2.G ? Color1.G - Color2.G : Color2.G - Color1.G; 
       int b = Color1.B > Color2.B ? Color1.B - Color2.B : Color2.B - Color1.B; 
       Image3.SetPixel(x, y, Color.FromArgb(r,g,b)); 
      } 
     } 
     int Difference = 0; 
     for (int x = 0; x < Image1.Width; x++) 
     { 
      for (int y = 0; y < Image1.Height; y++) 
      { 
       Color Color1 = Image3.GetPixel(x, y); 
       int Media = (Color1.R + Color1.G + Color1.B)/3; 
       if (Media > Tollerance) 
        Difference++; 
      } 
     } 
     double UsedSize = Image1Size > Image2Size ? Image2Size : Image1Size; 
     double result = Difference*100/UsedSize; 
     return Difference*100/UsedSize; 
    } 

这里测试了超过900个图像,它就像一个魅力X)