比较位图 - 比较法不工作
我想比较两个不同的意见,比较形象,看它是否是相同的或没有。这是我的代码...比较位图 - 比较法不工作
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。任何人都可以告诉我为什么我做错了?
不知道什么是错的代码,如果有的话,但你尝试Bitmap.sameAs(Bitmap)?
我得到错误“The method sameAs(Bitmap)是未定义的类型位图“ –
该方法标记 - 从以下版本:API级别12 - 所以我想不适用于您的平台版本。 – sudocode
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);
}
@ 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;
}
见下面我的反应。我也试过了上面的代码,它总是返回null作为.getDrawingCache()读取文档的位图,看起来好像它需要绘制视图 - 查看更新的响应 – Idistic