识别重复的图块

时间:2012-11-15 18:01:13

标签: java image hash bufferedimage tile

我有一个BufferedImage,其中包含多个图块。

我想要的是将瓷砖相互比较,看它们是否相同。

那么如何从可以在哈希算法中使用的缓冲图像中提取每个单独图块的数据来进行比较?

2 个答案:

答案 0 :(得分:2)

你不想比较哈希,只需逐个像素地浏览图像就足够了。

  assert imageA.getWidth() == imageB.getWidth();
  assert imageA.getHeight() == imageB.getHeight();

  for (int x = 0; x < imageA.getWidth(); x++)
  {
     for (int y = 0; y < imageA.getHeight(); y++)
     {
        assert imageA.getRGB(x, y) == imageB.getRGB(x, y);
     }
  }

答案 1 :(得分:1)

您可以使用MessageDigest。从页面引用:

  

此MessageDigest类为应用程序提供了a的功能   消息摘要算法,例如SHA-1或SHA-256。消息摘要   是安全的单向散列函数,它采用任意大小的数据和   输出固定长度的哈希值。

您可以搜索使用此类的示例,以了解如何使用不同的散列算法实现散列。您还可以使用其他库来简化您的工作,例如来自apache commons的DigestUtils。对于我们的情况,我将使用上面页面中的示例:

首先,获取一个图块的数据:我们查看制作图块的像素并读取rgb值。这将是一个int。注意到消息摘要的API,您需要使其成为字节数组并更新摘要。您可以创建一个从int获取字节数组的方法。或者你可以将整数连接成一个字符串,并获得整个字符串的完整数组,代表一个磁贴中的所有整数。然后你从那个字符串中获取字节。注意我将使用硬编码值仅用于第一个瓷砖上的演示,并且我不会处理异常等...:

StringBuilder firstImageRGBStr=new StringBuilder();
for (int i=0; i<32; i++)
 for (int j=0; j<32; j++)
   firstImageRGBStr.append(img.getRGB(i,j));


MessageDigest md = MessageDigest.getInstance("SHA");
byte[] firstImageDigest = md.digest(firstImageRGBStr.toString().getBytes());

现在您将字节数组存储为第一个tile的哈希值,以便将来进行比较。 请注意,您不需要为每个磁贴创建新的MessageDigest,因为在保存磁贴的散列后,您可以使用reset()重新使用另一个磁贴的消息摘要。

比较哈希现在成为包含哈希的字节数组的比较。并注意MessageDigest类有一个静态方法,它比较两个摘要,只是isEqual()