2011-05-25 87 views

回答

2

取決於你如何定義相同。如果你的意思是完全相同的文件,你可以做一個md5sum的文件。對於我猜想的每種類型的文件,這都是一樣的。

由於您專門對位圖文件進行了區分,因此您可能會對尺寸不同的文件感興趣。這有點困難。如果它們的大小相同但不完全相同(但看起來非常相似),則可以比較每個單獨的像素,並且如果足夠多的像素(閾值1)在顏色(閾值2)內足夠接近,則可以聲明他們是一樣的。

您可以getPixel(int,int)得到的顏色,看到this page

14

應該是這樣的:

public boolean equals(Bitmap bitmap1, Bitmap bitmap2) { 
    ByteBuffer buffer1 = ByteBuffer.allocate(bitmap1.getHeight() * bitmap1.getRowBytes()); 
    bitmap1.copyPixelsToBuffer(buffer1); 

    ByteBuffer buffer2 = ByteBuffer.allocate(bitmap2.getHeight() * bitmap2.getRowBytes()); 
    bitmap2.copyPixelsToBuffer(buffer2); 

    return Arrays.equals(buffer1.array(), buffer2.array()); 
} 
+3

內存不足異常 – Trikaldarshi 2013-06-28 12:09:48

+0

@Photon,我沒有遇到過這種方法的任何異常 – Exterminator13 2013-07-04 09:22:59

+3

內存不足異常即使在galaxy S3上 – Trikaldarshi 2013-07-04 11:06:24

9

這個問題似乎很老,但我今天在這個問題上花了一些時間,這裏是我沒有。

private static boolean compare(Bitmap b1, Bitmap b2) { 
    if (b1.getWidth() == b2.getWidth() && b1.getHeight() == b2.getHeight()) { 
     int[] pixels1 = new int[b1.getWidth() * b1.getHeight()]; 
     int[] pixels2 = new int[b2.getWidth() * b2.getHeight()]; 
     b1.getPixels(pixels1, 0, b1.getWidth(), 0, 0, b1.getWidth(), b1.getHeight()); 
     b2.getPixels(pixels2, 0, b2.getWidth(), 0, 0, b2.getWidth(), b2.getHeight()); 
     if (Arrays.equals(pixels1, pixels2)) { 
      return true; 
     } else { 
      return false; 
     } 
    } else { 
     return false; 
    } 
} 
+3

您可以簡化語句以返回Arrays.equals(pixels1,pixels2);代替「if(Arrays.equals(pixels1,pixels2)){ return true; } else { return false; }」 – ademar111190 2014-07-29 19:42:31

0

對於小於12的API,主要問題是對於大文件分辨率,我們得到OutOfMemory錯誤。我解決它通過(在本例中10)隨地吐痰位圖成塊,然後通過字節比較它們:

private boolean compareBitmaps(Bitmap bitmap1, Bitmap bitmap2) 
{ 
    if (Build.VERSION.SDK_INT > 11) 
    { 
     return bitmap1.sameAs(bitmap2); 
    } 

    int chunkNumbers = 10; 
    int rows, cols; 
    int chunkHeight, chunkWidth; 
    rows = cols = (int) Math.sqrt(chunkNumbers); 
    chunkHeight = bitmap1.getHeight()/rows; 
    chunkWidth = bitmap1.getWidth()/cols; 

    int yCoord = 0; 
    for (int x = 0; x < rows; x++) 
    { 
     int xCoord = 0; 
     for (int y = 0; y < cols; y++) 
     { 
      try 
      { 
       Bitmap bitmapChunk1 = Bitmap.createBitmap(bitmap1, xCoord, yCoord, chunkWidth, chunkHeight); 
       Bitmap bitmapChunk2 = Bitmap.createBitmap(bitmap2, xCoord, yCoord, chunkWidth, chunkHeight); 

       if (!sameAs(bitmapChunk1, bitmapChunk2)) 
       { 
        recycleBitmaps(bitmapChunk1, bitmapChunk2); 
        return false; 
       } 

       recycleBitmaps(bitmapChunk1, bitmapChunk2); 

       xCoord += chunkWidth; 
      } 
      catch (Exception e) 
      { 
       return false; 
      } 
     } 
     yCoord += chunkHeight; 
    } 

    return true; 
} 

private boolean sameAs(Bitmap bitmap1, Bitmap bitmap2) 
{ 
    // Different types of image 
    if (bitmap1.getConfig() != bitmap2.getConfig()) 
     return false; 

    // Different sizes 
    if (bitmap1.getWidth() != bitmap2.getWidth()) 
     return false; 

    if (bitmap1.getHeight() != bitmap2.getHeight()) 
     return false; 

    int w = bitmap1.getWidth(); 
    int h = bitmap1.getHeight(); 

    int[] argbA = new int[w * h]; 
    int[] argbB = new int[w * h]; 

    bitmap1.getPixels(argbA, 0, w, 0, 0, w, h); 
    bitmap2.getPixels(argbB, 0, w, 0, 0, w, h); 

    // Alpha channel special check 
    if (bitmap1.getConfig() == Bitmap.Config.ALPHA_8) 
    { 
     final int length = w * h; 
     for (int i = 0; i < length; i++) 
     { 
      if ((argbA[i] & 0xFF000000) != (argbB[i] & 0xFF000000)) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

    return Arrays.equals(argbA, argbB); 
} 

private void recycleBitmaps(Bitmap bitmap1, Bitmap bitmap2) 
{ 
    bitmap1.recycle(); 
    bitmap2.recycle(); 
    bitmap1 = null; 
    bitmap2 = null; 
}