Comparing Bitmap images in Android
Is there any way to check if bitm开发者_如何学Pythonaps are the same? can someone help me out?
Bitmap class has method "sameAs" you can use that method to compare two bitmap
http://developer.android.com/reference/android/graphics/Bitmap.html#sameAs%28android.graphics.Bitmap%29
It should be something like this:
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());
}
This question seems old but I spent some time on this issue today and here is what I did.
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;
}
}
Depending on how you define the same. If you mean the exact same file, you can do an md5sum of the files. That will be the same for every type of file I guess.
Because you specifically make the distinction for bitmap files, you might be interested in files that differ in size. That's a bit harder. If they are the same size, but not completely the same (but look really much like eachother) you can compare each separate pixel, and if enough pixels (threshold 1) are close enough to each other in color (threshold 2) you can declare them as being the same.
You can getPixel(int,int)
to get the color, see this page
The main issue for APIs less than 12 is that we get OutOfMemory
error for big file resolutions. I solved it by spitting bitmaps into pieces (10 in the example) and then comparing them by Bytes:
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;
}
精彩评论