来自 Pillow 的同一来源的不同图像数据
Different image data from the same source with Pillow
我目前正在将一个脚本从 windows 主机的图像创建本地敏感散列到 debian 主机。
我的问题是 Pillow returns 来自两个平台上相同源图像的不同图像数据。
我只观察到 jpeg 的这种行为。
测试用例:
from PIL import Image
import md5
import urllib2
from cStringIO import StringIO
urls = ("https://i.imgur.com/Mx6NQwM.jpg","https://i.imgur.com/MN1TKu5.png")
print("VERSION %s" % Image.VERSION)
for url in urls:
response = urllib2.urlopen(url).read()
img = Image.open(StringIO(response)).convert("RGB")
img_md5 = "".join("".join(map(chr, x)) for x in img.getdata())
print("URL: %s" % url)
print("Plain md5:\t%s" % md5.new(response.read()).hexdigest())
print("Image md5:\t%s" % md5.new(img_md5).hexdigest())
应该return 两个系统上的 md5 散列值相同。
我的结果:
Windows 7:
VERSION 1.1.7
URL: https://i.imgur.com/Mx6NQwM.jpg
Plain md5: 4aacd5b92575ffca6d0ab884f95cc1f9
Image md5: 10eaf568f4d9d33c722ea702fc4d1025
URL: https://i.imgur.com/MN1TKu5.png
Plain md5: d05e6dc1311339b806e5998f15fc818c
Image md5: 38fc986c5cd9605038ee627b11687344
Debian 杰西:
VERSION 1.1.7
URL: https://i.imgur.com/Mx6NQwM.jpg
Plain md5: 4aacd5b92575ffca6d0ab884f95cc1f9
Image md5: 7347c6286f4d917649d967a5025e392e
URL: https://i.imgur.com/MN1TKu5.png
Plain md5: d05e6dc1311339b806e5998f15fc818c
Image md5: 38fc986c5cd9605038ee627b11687344
LSH 有点相似,但不同之处足以引起问题。
两个系统上的 pillow 版本都是 2.9.0。
有什么方法可以在 debian 系统上获得与我在 windows 上相同的像素值吗?
总的来说:有人知道为什么会这样吗?
我个人不认为不同机器和/或操作系统之间的内部图像表示一定是相同的——尤其是当其中一个是 64 位而另一个是 32 位时。这不能保证,这就是你计算图像 MD5 的依据——你在两个系统上得到相同的文件 MD5,所以如果你需要图像数据 MD5,文件是相同的,那么你应该首先转换为已知特征的位图——然后 MD5 位图而不是 "image".
我"solved"我的问题。
我不小心在 windows 主机上安装了 PIL
和 Pillow
。
看起来它选择使用 PIL
版本。
在 debian 机器上使用 PIL
后,两台机器上的结果也是一样的。
通常,将 PIL
端升级为使用 Pillow
会更明智,但在我的情况下,我需要生成与 PIL 版本完全相同的哈希值。
故事的寓意:PIL
和Pillow
加载相同图像时可能return不同的图像数据。
我目前正在将一个脚本从 windows 主机的图像创建本地敏感散列到 debian 主机。
我的问题是 Pillow returns 来自两个平台上相同源图像的不同图像数据。
我只观察到 jpeg 的这种行为。
测试用例:
from PIL import Image
import md5
import urllib2
from cStringIO import StringIO
urls = ("https://i.imgur.com/Mx6NQwM.jpg","https://i.imgur.com/MN1TKu5.png")
print("VERSION %s" % Image.VERSION)
for url in urls:
response = urllib2.urlopen(url).read()
img = Image.open(StringIO(response)).convert("RGB")
img_md5 = "".join("".join(map(chr, x)) for x in img.getdata())
print("URL: %s" % url)
print("Plain md5:\t%s" % md5.new(response.read()).hexdigest())
print("Image md5:\t%s" % md5.new(img_md5).hexdigest())
应该return 两个系统上的 md5 散列值相同。
我的结果:
Windows 7:
VERSION 1.1.7
URL: https://i.imgur.com/Mx6NQwM.jpg
Plain md5: 4aacd5b92575ffca6d0ab884f95cc1f9
Image md5: 10eaf568f4d9d33c722ea702fc4d1025
URL: https://i.imgur.com/MN1TKu5.png
Plain md5: d05e6dc1311339b806e5998f15fc818c
Image md5: 38fc986c5cd9605038ee627b11687344
Debian 杰西:
VERSION 1.1.7
URL: https://i.imgur.com/Mx6NQwM.jpg
Plain md5: 4aacd5b92575ffca6d0ab884f95cc1f9
Image md5: 7347c6286f4d917649d967a5025e392e
URL: https://i.imgur.com/MN1TKu5.png
Plain md5: d05e6dc1311339b806e5998f15fc818c
Image md5: 38fc986c5cd9605038ee627b11687344
LSH 有点相似,但不同之处足以引起问题。
两个系统上的 pillow 版本都是 2.9.0。
有什么方法可以在 debian 系统上获得与我在 windows 上相同的像素值吗?
总的来说:有人知道为什么会这样吗?
我个人不认为不同机器和/或操作系统之间的内部图像表示一定是相同的——尤其是当其中一个是 64 位而另一个是 32 位时。这不能保证,这就是你计算图像 MD5 的依据——你在两个系统上得到相同的文件 MD5,所以如果你需要图像数据 MD5,文件是相同的,那么你应该首先转换为已知特征的位图——然后 MD5 位图而不是 "image".
我"solved"我的问题。
我不小心在 windows 主机上安装了 PIL
和 Pillow
。
看起来它选择使用 PIL
版本。
在 debian 机器上使用 PIL
后,两台机器上的结果也是一样的。
通常,将 PIL
端升级为使用 Pillow
会更明智,但在我的情况下,我需要生成与 PIL 版本完全相同的哈希值。
故事的寓意:PIL
和Pillow
加载相同图像时可能return不同的图像数据。