from exiftool python exif

python - exiftool - Calcular el hash de solo los datos de la imagen central(excluyendo los metadatos) para una imagen



exiftool python (4)

Estoy escribiendo un script para calcular la suma MD5 de una imagen excluyendo la etiqueta EXIF.

Para hacer esto con precisión, necesito saber dónde se encuentra la etiqueta EXIF ​​en el archivo (inicio, medio, fin) para poder excluirla.

¿Cómo puedo determinar dónde está ubicada la etiqueta en el archivo?

Las imágenes que estoy escaneando están en el formato TIFF, JPG, PNG, BMP, DNG, CR2, NEF y algunos videos MOV, AVI y MPG.


Es mucho más fácil usar la biblioteca de imágenes de Python para extraer los datos de la imagen (ejemplo en iPython):

In [1]: import Image In [2]: import hashlib In [3]: im = Image.open(''foo.jpg'') In [4]: hashlib.md5(im.tostring()).hexdigest() Out[4]: ''171e2774b2549bbe0e18ed6dcafd04d5''

Esto funciona en cualquier tipo de imagen que PIL pueda manejar. El método tostring devuelve una cadena que contiene los datos de píxeles.

Por cierto, el hash MD5 ahora se ve como bastante débil. Mejor usar SHA512:

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

En mi máquina, el cálculo de la suma de comprobación MD5 para un JPEG de 2500x1600 toma alrededor de 0.07 segundos. Usando SHA512, toma 0,10 segundos.

Para películas, puede extraer cuadros de ellos con, por ejemplo, ffmpeg , y luego procesarlos como se muestra arriba.


Puede utilizar la stream que es parte de la suite ImageMagick :

$ stream -map rgb -storage-type short image.tif - | sha256sum d39463df1060efd4b5a755b09231dcbc3060e9b10c5ba5760c7dbcd441ddcd64 -

o

$ sha256sum <(stream -map rgb -storage-type short image.tif -) d39463df1060efd4b5a755b09231dcbc3060e9b10c5ba5760c7dbcd441ddcd64 /dev/fd/63

Este ejemplo es para un archivo TIFF que es RGB con 16 bits por muestra (es decir, 48 bits por píxel). Así que uso map to rgb y un storage-type short (puede usar char aquí si los valores RGB son de 8 bits).

Este método reporta el mismo hash de signature que los informes de comando detallados de Imagemagick identify :

$ identify -verbose image.tif | grep signature signature: d39463df1060efd4b5a755b09231dcbc3060e9b10c5ba5760c7dbcd441ddcd64

(para ImageMagick v6.x; el hash reportado por identify en la versión 7 es different al obtenido usando stream , pero esta última puede ser reproducida por cualquier herramienta capaz de extraer los datos de mapa de bits en bruto, como dcraw para algunos tipos de imágenes).


Una forma sencilla de hacerlo es hacer un hash de los datos de la imagen central. Para PNG, puede hacer esto contando solo los "fragmentos críticos" (es decir, los que comienzan con letras mayúsculas). JPEG tiene una estructura de archivos similar pero más simple.

El hash visual en ImageMagick descomprime la imagen a medida que lo hace. En su caso, podría codificar los datos de la imagen comprimida de inmediato, por lo que (si se implementa correctamente) debería ser tan rápido como el hash del archivo en bruto.

Este es un pequeño script de Python que ilustra la idea. Puede o no funcionar para usted, pero al menos debería dar una indicación de lo que quiero decir :)

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"))


Yo usaría un separador de metadatos para preprocesar su hashing:

Desde el paquete ImageMagick tienes ...

mogrify -strip blah.jpg

y si lo haces

identify -list format

Aparentemente funciona con todos los formatos citados.