25

EXIF タグを除いた画像の MD5 合計を計算するスクリプトを作成しています。

これを正確に行うには、EXIF タグがファイル内のどこにあるか (先頭、中間、末尾) を把握して、それを除外できるようにする必要があります。

タグがファイル内のどこにあるかを確認するにはどうすればよいですか?

スキャンしている画像は、TIFF、JPG、PNG、BMP、DNG、CR2、NEF の形式で、一部のビデオは MOV、AVI、MPG です。

4

4 に答える 4

22

Python Imaging Library を使用して画像データを抽出する方がはるかに簡単です (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'

これは、PIL が処理できるすべてのタイプの画像で機能します。このtobytesメソッドは、ピクセル データを含む文字列を返します。

ところで、MD5 ハッシュは現在かなり弱いと見なされています。SHA512 を使用することをお勧めします。

In [6]: hashlib.sha512(im.tobytes()).hexdigest()
Out[6]: '6361f4a2722f221b277f81af508c9c1d0385d293a12958e2c56a57edf03da16f4e5b715582feef3db31200db67146a4b52ec3a8c445decfc2759975a98969c34'

私のマシンでは、2500x1600 JPEG の MD5 チェックサムを計算するのに約 0.07 秒かかります。SHA512 を使用すると、0.10 秒かかります。完全な例:

#!/usr/bin/env python3

from PIL import Image
import hashlib
import sys

im = Image.open(sys.argv[1])
print(hashlib.sha512(im.tobytes()).hexdigest(), end="")

ムービーの場合、たとえばffmpegを使用してフレームを抽出し、上記のように処理できます。

于 2012-08-29T10:33:56.830 に答える
8

これを行う簡単な方法の 1 つは、コアの画像データをハッシュすることです。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"))
于 2012-04-09T15:01:49.433 に答える
1

メタデータ ストリッパーを使用して、ハッシュを前処理します。

あなたが持っているImageMagickパッケージから...

mogrify -strip blah.jpg

もしそうなら

identify -list format 

引用されたすべてのフォーマットで動作するようです。

于 2012-08-29T21:04:00.913 に答える