ビットマップが同じかどうかを確認するにする方法はありますか?誰かが私を助けることができますか?
同じものをどのように定義するかに応じて。 まったく同じファイルを意味する場合は、ファイルのmd5sumを実行できます。これは、私が推測するすべての種類のファイルで同じです。
特にビットマップファイルを区別するため、サイズが異なるファイルに関心があるかもしれません。それは少し難しいです。それらが同じサイズであるが完全に同じではない場合(ただし、互いに非常によく似ている場合)、それぞれの個別のピクセルを比較できます。十分なピクセル(しきい値1)が色(しきい値2)で互いに十分に近い場合は、宣言できます。それらは同じものとして。
getPixel(int,int)
で色を取得できます。 このページ を参照してください。
ビットマップクラスにはメソッド「sameAs」があり、そのメソッドを使用して2つのビットマップを比較できます
次のようになります。
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());
}
この質問は古いようですが、今日はこの問題に時間を費やしました。これが私がしたことです。
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;
}
}
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;
}