2009-03-16 9 views
3

Ich möchte zwei BMP-Dateien vergleichen. Ich dachte an zwei Ansätze:Vergleich von BMP-Dateien?

  1. den Header sowie die Header-Informationen der beiden Dateien
  2. wandeln die bmp-Datei binär zu vergleichen und tun dann dem obigen Vergleich

Aber ich Ich weiß nicht, wie ich anfangen soll und was ein besserer Ansatz sein wird. Ich würde mich freuen, wenn mir jemand helfen könnte!

+0

Welche Art von Vergleich machen Sie? Möchten Sie prüfen, ob es sich um identische Kopien handelt? oder möchten Sie überprüfen, ob es sich um ähnliche Bilder handelt? Die erste ist einfach zu machen und die zweite ist ein bisschen schwieriger. – Niyaz

Antwort

1

Ich weiß nicht, auf welcher Plattform Sie diese umsetzen wollen, aber hier sind einige Code-Schnipsel, die nützlich sein könnten:

Compare two images with C#

Dies ist ein Ausschnitt 2 Bilder vergleichen zu Schau, ob sie gleich sind. Diese Methode konvertiert zuerst jedes Bitmap in ein Byte-Array und erhält dann den Hash jedes Arrays. Wir durchlaufen dann jeweils in den Hash, um zu sehen, ob sie übereinstimmen.

/// <summary> 
/// method for comparing 2 images to see if they are the same. First 
/// we convert both images to a byte array, we then get their hash (their 
/// hash should match if the images are the same), we then loop through 
/// each item in the hash comparing with the 2nd Bitmap 
/// </summary> 
/// <param name="bmp1"></param> 
/// <param name="bmp2"></param> 
/// <returns></returns> 
public bool doImagesMatch(ref Bitmap bmp1, ref Bitmap bmp2) 
{ 
    ... 
} 
0

Nun, haben Sie mindestens zwei Möglichkeiten:

  • Die Bilder sind meist die gleichen
    In diesem Fall würde ich splattne Lösung mit

    ein vergleichen empfehlen
  • Die Bilder sind normalerweise unterschiedlich, und nur manchmal die gleichen
    In diesem Fall kann es sein, dass Sie die Ähnlichkeit zwischen den beiden Bildern mit einem schnellen Vergleich des Informationsheaders ablehnen können (denken Sie "Ist die Größe gleich?") Und nur den vollständigen Vergleich durchführen, wenn die Information nicht eindeutig ist (dh die Größe ist das gleiche)

0

Möglicherweise möchten Sie eine Erweiterungsmethode in .NET verwenden 3.0+ hierfür die vergleichen Methode auf allen Bitmaps zu entlarven:

public static bool Compare(this Bitmap bmp1, Bitmap bmp2) 
    { 
     //put your comparison logic here 
    } 
0

Was Sie sind Vergleichen für? Suchst du, ob 2 Bilder genau gleich sind? Oder brauchst du Grad Unterschied? Für genaue Übereinstimmungen wie zum Erstellen und Vergleichen von Hashes beider Dateien?

0

Die obigen Lösungen funktionierten nicht für mich, wenn ich zwei Bilder hatte, die sich nur in der Farbtiefe unterschieden - eine war 32bpp und die andere war 8bpp. Die Lösung, die ich ankam, benutzte LockBits, um alle Bilder in 32bpp zu konvertieren, Marshal.Copy(), um die Daten in ein Array zu bekommen und dann einfach die Arrays zu vergleichen.

/// <summary> 
/// Compares two images for pixel equality 
/// </summary> 
/// <param name="fname1">first image file</param> 
/// <param name="fname2">second image file</param> 
/// <returns>true if images are identical</returns> 
public static string PageCompare(string fname1, string fname2) { 
    try { 
     using (Bitmap bmp1 = new Bitmap(fname1)) 
     using (Bitmap bmp2 = new Bitmap(fname2)) { 
      if (bmp1.Height != bmp2.Height || bmp1.Width != bmp2.Width) 
       return false; 

      // Convert image to int32 array with each int being one pixel 
      int cnt = bmp1.Width * bmp1.Height * 4/4; 
      BitmapData bmData1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), 
       ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
      BitmapData bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), 
       ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 

      Int32[] rgbValues1 = new Int32[cnt]; 
      Int32[] rgbValues2 = new Int32[cnt]; 

      // Copy the ARGB values into the array. 
      System.Runtime.InteropServices.Marshal.Copy(bmData1.Scan0, rgbValues1, 0, cnt); 
      System.Runtime.InteropServices.Marshal.Copy(bmData2.Scan0, rgbValues2, 0, cnt); 

      bmp1.UnlockBits(bmData1); 
      bmp2.UnlockBits(bmData2); 
      for (int i = 0; i < cnt; ++i) { 
       if (rgbValues1[i] != rgbValues2[i]) 
        return false; 
      } 
     } 
    } 
    catch (Exception ex) { 
     return false; 
    } 
    // We made it this far so the images must match 
    return true; 
}