2016-07-12 21 views
0

我正在使用Windows窗體中的項目,並且遇到問題。在這個項目中,我必須將屏幕截圖與文件中的圖像進行比較我找到了很好的互聯網比較方法,它似乎正在工作。例如:我從網站取消了Facebook徽標並將其保存在桌面上。當我將這個Logo與自己進行比較時(我正在製作一個徽標的屏幕截圖,並且將該屏幕截圖與Logo進行比較),此方法正常工作(它表示屏幕截圖包含徽標),但是當我在其網站上製作屏幕截圖並比較它與Logo,這種方法說截圖不包含Logo。無法比較屏幕截圖和圖像

我使用這個方法比較:

public static Rectangle searchBitmap(Bitmap smallBmp, Bitmap bigBmp, double tolerance) 
{ 
    BitmapData smallData = 
     smallBmp.LockBits(new Rectangle(0, 0, smallBmp.Width, smallBmp.Height), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, 
      System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
    BitmapData bigData = 
    bigBmp.LockBits(new Rectangle(0, 0, bigBmp.Width, bigBmp.Height), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, 
      System.Drawing.Imaging.PixelFormat.Format24bppRgb); 

    int smallStride = smallData.Stride; 
    int bigStride = bigData.Stride; 

    int bigWidth = bigBmp.Width; 
    int bigHeight = bigBmp.Height - smallBmp.Height + 1; 
    int smallWidth = smallBmp.Width * 3; 
    int smallHeight = smallBmp.Height; 

    Rectangle location = Rectangle.Empty; 
    int margin = Convert.ToInt32(255.0 * tolerance); 

    unsafe 
    { 
     byte* pSmall = (byte*)(void*)smallData.Scan0; 
     byte* pBig = (byte*)(void*)bigData.Scan0; 

     int smallOffset = smallStride - smallBmp.Width * 3; 
     int bigOffset = bigStride - bigBmp.Width * 3; 
     bool matchFound = true; 

     for (int y = 0; y < bigHeight; y++) 
     { 
      for (int x = 0; x < bigWidth; x++) 
      { 
       byte* pBigBackup = pBig; 
       byte* pSmallBackup = pSmall; 

       //Look for the small picture. 
       for (int i = 0; i < smallHeight; i++) 
       { 
        int j = 0; 
        matchFound = true; 
        for (j = 0; j < smallWidth; j++) 
        { 
         //With tolerance: pSmall value should be between margins. 
         int inf = pBig[0] - margin; 
         int sup = pBig[0] + margin; 
         if (sup < pSmall[0] || inf > pSmall[0]) 
         { 
          matchFound = false; 
          break; 
         } 

         pBig++; 
         pSmall++; 
        } 

        if (!matchFound) break; 

        //We restore the pointers. 
        pSmall = pSmallBackup; 
        pBig = pBigBackup; 

        //Next rows of the small and big pictures. 
        pSmall += smallStride * (1 + i); 
        pBig += bigStride * (1 + i); 
       } 

       //If match found, we return. 
       if (matchFound) 
       { 
        location.X = x; 
        location.Y = y; 
        location.Width = smallBmp.Width; 
        location.Height = smallBmp.Height; 
        break; 
       } 
       //If no match found, we restore the pointers and continue. 
       else 
       { 
        pBig = pBigBackup; 
        pSmall = pSmallBackup; 
        pBig += 3; 
       } 
      } 

      if (matchFound) break; 

      pBig += bigOffset; 
     } 
    } 

    bigBmp.UnlockBits(bigData); 
    smallBmp.UnlockBits(smallData); 

    return location; 
} 

此方法返回一個矩形的 「位置」。如果(location.Width == 0 || location.height == 0),則表示截圖不包含圖像。 什麼問題?

+0

一個可能的原因是,屏幕截圖使用屏幕分辨率,所以屏幕截圖的大小可能與您的模板不同。在你的代碼中,你認爲'logo'的大小相同。 – urlreader

+0

屏幕截圖尺寸比模板大,但是當我製作圖片截圖(不是來自瀏覽器)時,它比識別截圖中的圖片更大。另一方面,當我在瀏覽器中製作屏幕截圖時,它無法識別他。 –

+0

檢查1)來自瀏覽器的屏幕截圖的標誌大小; 2)不是來自瀏覽器;很可能,大小是不一樣的(儘管也許是相似的)。所以,爲了匹配它們,你需要考慮:1)標誌的大小; 2)而不是匹配的RGB與小的閾值,使用其他功能,如邊緣,... – urlreader

回答

0

如果屏幕截圖包含邊框周圍的空白區域,它很可能與圖像不匹配(除非屏幕截圖是整個屏幕)。

+0

我知道大約在哪裏這個標誌將出現,所以我做一個屏幕截圖不是在所有屏幕上,我從桌面切割矩形和該矩形是一個截圖,它不僅包含一個圖像,但它也包含它'背景或另一個標誌。 –