Android计算位图的哈希值

时间:2012-06-20 20:57:21

标签: android hash bitmap

我想计算不同位图的SHA1哈希值(不强制使用SHA)。 问题是有一些基本相同的位图(验证码),但名称经常变化。

我发现了这个:

Compute SHA256 Hash in Android/Java and C#

但这不是我想要的解决方案。

Bitmap.hashCode()只生成一个Integer,当我正确时

  

返回此对象的整数哈希码。通过契约,equals(Object)返回true的任何两个对象都必须返回相同的哈希码值。这意味着Object的子类通常会覆盖两个方法或两个方法。

我不想要对象的哈希码,我想要位图内容的哈希码。 感谢名单!

4 个答案:

答案 0 :(得分:6)

在Android 3.1或更高版本(API级别12)中,Bitmap上有一个名为sameAs()的方法,它会比较像素并返回两个代表相同图像的方法。它在本机代码中执行此操作,因此它相对较快。

如果必须以较低的API级别为目标,则必须编写一个迭代两个对象的每个像素的方法,并查看它们是否匹配。如果在Java代码中完成,这将是一个非常密集的过程,因此您可以考虑使用可以从应用程序调用的NDK编写一个小例程,以便在本机代码中进行比较(NDK中有Bitmap API,因此您可以轻松实现得到像素缓冲区。)

如果您选择在Java中执行此操作,getPixels()将帮助您获取可在两个图像之间进行比较的像素数据数组。

HTH

答案 1 :(得分:2)

到目前为止,我在Kotlin中找到的最快解决方案:

fun Bitmap.hash(): Int {
    val buffer: ByteBuffer = ByteBuffer.allocate(this.height * this.rowBytes)
    this.copyPixelsToBuffer(buffer)
    return buffer.hashCode()
}

比接受的答案快近100倍

答案 2 :(得分:1)

您可以尝试仅使用位图中的Pixel来编写自己的函数:

public long hashBitmap(Bitmap bmp){
  long hash = 31 //or a higher prime at your choice
  for(int x = 0; x < bmp.getWidth(); x++){
    for (int y = 0; y < bmp.getHeight(); y++){
      hash *= (bmp.getPixel(x,y) + 31);
    }
  }
  return hash;
}

如果它只是比较两个图像,你可以优化这个例程,只是每秒或x像素哈希

答案 3 :(得分:0)

这是使用Arrays.hashCodebitmap.getPixels

来计算位图哈希的一种更原始​​的方法。
int hash(Bitmap bitmap){
   int[] buffer = new int[bitmap.getWidth(), bitmap.getHeight()];
   bitmap.getPixels(buffer, 0, 0, 0, 0, bitmap.getWidth(), bitmap.getHeight());
   return Arrays.hashCode(buffer);
}