2012-06-19 122 views
0

我想比较两个不同的意见,比较形象,看它是否是相同的或没有。这是我的代码...比较位图 - 比较法不工作

public boolean equals(View view1, View view2){ 

    view1.setDrawingCacheEnabled(true); 
    view1.buildDrawingCache(); 
    Bitmap b1 = view1.getDrawingCache(); 

    view2.setDrawingCacheEnabled(true); 
    view2.buildDrawingCache(); 
    Bitmap b2 = view2.getDrawingCache(); 

    ByteBuffer buffer1 = ByteBuffer.allocate(b1.getHeight() * b1.getRowBytes()); 
    b1.copyPixelsToBuffer(buffer1); 

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

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

但是,无论如何这都会返回true。任何人都可以告诉我为什么我做错了?

+0

见下面我的反应。我也试过了上面的代码,它总是返回null作为.getDrawingCache()读取文档的位图,看起来好像它需要绘制视图 - 查看更新的响应 – Idistic

回答

1

不知道什么是错的代码,如果有的话,但你尝试Bitmap.sameAs(Bitmap)

+0

我得到错误“The method sameAs(Bitmap)是未定义的类型位图“ –

+0

该方法标记 - 从以下版本:API级别12 - 所以我想不适用于您的平台版本。 – sudocode

0

UPDATE:下面的代码工作正常,但上述代码似乎总是从.getDrawingCache()不知道这是你的问题或没有返回null。我没有时间去太深考虑这一点,但你可能会检查getDrawingCache() returns null看到一个类似的问题是如何解决的,否则,请您提供logcat的。


下面是API 15(不是真的检查过严格)的sameAs的功能,在API推出了端口12

一个他们做的特别检查,看是否该图像是alpha通道,以及一些优化的,以避免阵列检查,如果可能的(可能不是你的使用情况的问题),还不如采取开源的优势,当你可以;-)

boolean SameAs(Bitmap A, Bitmap B) { 

    // Different types of image 
    if(A.getConfig() != B.getConfig()) 
     return false; 

    // Different sizes 
    if (A.getWidth() != B.getWidth()) 
     return false; 
    if (A.getHeight() != B.getHeight()) 
     return false; 

    // Allocate arrays - OK because at worst we have 3 bytes + Alpha (?) 
    int w = A.getWidth(); 
    int h = A.getHeight(); 

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

    A.getPixels(argbA, 0, w, 0, 0, w, h); 
    B.getPixels(argbB, 0, w, 0, 0, w, h); 

    // Alpha channel special check 
    if (A.getConfig() == Config.ALPHA_8) { 
     // in this case we have to manually compare the alpha channel as the rest is garbage. 
     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); 
} 
+0

当我将它复制到我的代码中时,它在“A.getPixels()”上崩溃-_- –

+0

@LiLi Liu让我看看 – Idistic

+0

@LiLi Liu我用相同,不同大小,相同大小的不同内容它工作得很好。请发布您的logcat输出,以便我们可以看到确切的错误 – Idistic

0

@ Idistic的回答帮我再弄该解决方案也适用于分辨率更高的图像这可能导致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; 
}