我正在编写一个脚本来计算除EXIF标签之外的图像的MD5总和.
为了准确地做到这一点,我需要知道EXIF标记在文件中的位置(开头,中间,结尾),以便我可以将其排除.
如何确定标签在文件中的位置?
我正在扫描的图像格式为TIFF,JPG,PNG,BMP,DNG,CR2,NEF,以及一些视频MOV,AVI和MPG.
Rol*_*ith 17
这是很多更容易使用Python图像库中提取的图片数据(例如的IPython):
In [1]: import Image
In [2]: import hashlib
In [3]: im = Image.open('foo.jpg')
In [4]: hashlib.md5(im.tobytes()).hexdigest()
Out[4]: '171e2774b2549bbe0e18ed6dcafd04d5'
Run Code Online (Sandbox Code Playgroud)
这适用于PIL可以处理的任何类型的图像.该tobytes方法返回包含像素数据的字符串.
顺便说一下,MD5哈希现在看起来很弱.最好使用SHA512:
In [6]: hashlib.sha512(im.tobytes()).hexdigest()
Out[6]: '6361f4a2722f221b277f81af508c9c1d0385d293a12958e2c56a57edf03da16f4e5b715582feef3db31200db67146a4b52ec3a8c445decfc2759975a98969c34'
Run Code Online (Sandbox Code Playgroud)
在我的机器上,计算2500x1600 JPEG的MD5校验和大约需要0.07秒.使用SHA512需要0.10秒.
对于电影,您可以使用例如ffmpeg从中提取帧,然后如上所示处理它们.
一种简单的方法是对核心图像数据进行散列.对于PNG,您可以通过仅计算"关键块"(即以大写字母开头的那些)来完成此操作.JPEG具有类似但更简单的文件结构.
ImageMagick中的可视化哈希在对图像进行哈希处理时对其进行解压缩.在您的情况下,您可以立即散列压缩的图像数据,因此(如果正确实现)它应该与散列原始文件一样快.
这是一个小Python脚本,说明了这个想法.它可能适用于您,也可能不适合您,但它至少应该表明我的意思:)
import struct
import os
import hashlib
def png(fh):
hash = hashlib.md5()
assert fh.read(8)[1:4] == "PNG"
while True:
try:
length, = struct.unpack(">i",fh.read(4))
except struct.error:
break
if fh.read(4) == "IDAT":
hash.update(fh.read(length))
fh.read(4) # CRC
else:
fh.seek(length+4,os.SEEK_CUR)
print "Hash: %r" % hash.digest()
def jpeg(fh):
hash = hashlib.md5()
assert fh.read(2) == "\xff\xd8"
while True:
marker,length = struct.unpack(">2H", fh.read(4))
assert marker & 0xff00 == 0xff00
if marker == 0xFFDA: # Start of stream
hash.update(fh.read())
break
else:
fh.seek(length-2, os.SEEK_CUR)
print "Hash: %r" % hash.digest()
if __name__ == '__main__':
png(file("sample.png"))
jpeg(file("sample.jpg"))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5529 次 |
| 最近记录: |