位图的 Android 计算哈希



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

我发现这个:

在 Android/Java 和 C# 中计算 SHA256 哈希

但这不是我想要的孤独。

Bitmap.hashCode(),只生成一个整数,当 im right

返回此对象的整数哈希代码。根据协定,等于(对象)返回 true 的任何两个对象必须返回相同的哈希代码值。这意味着 Object 的子类通常覆盖这两个方法或都不覆盖任何方法。

我不想要对象的哈希代码

,我想要位图内容的哈希代码。谢谢!

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

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

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

这是一种更原生的计算位图哈希的方法,使用 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);
}

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

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

比接受的答案快近 100 倍

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

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像素进行哈希处理

类似的问题,这对我有用(解决了为特定位图获取新名称的问题,因此我可以检查它是否已存储):

fun getUniqueBitmapFileName(bitmap: Bitmap): String {
    val buffer = ByteBuffer.allocate(bitmap.getByteCount())
    bitmap.copyPixelsToBuffer(buffer)
    return Arrays.hashCode(buffer.array()).toString()
}

最新更新