Los dispositivos como cámaras digitales, teléfonos inteligentes y escáneres utilizan el estándar EXIF para guardar archivos de imagen o audio. Este estándar contiene muchas etiquetas útiles para extraer que pueden ser útiles para la investigación forense, como la marca, el modelo del dispositivo, la fecha y hora exactas de creación de la imagen e incluso la información del GPS en algunos dispositivos. Pues bien, en esta ocasión nos proponemos crear una sencilla aplicación gráfica, que , seleccionado un archivo de imagen, nos muestre (en el caso que los haya) en un display los datos EXIF de la imagen:
Como es habitual, para crear nuestra aplicación, deberemos empezar importando los recursos necesarios que vamos a emplear. Que en este caso serán (fundamentalmente) las librerías «Tkinter» (preeinstalada con el interprete de Python) y la librería para manipulado de archivos de imagen «Pillow» (la cual deberemos instalar previamente, con el comando «pip install pil«). Una vez que lo tengamos todo listo, iniciaremos la elaboración de nuestro programa, realizando las importaciones pertinentes:
Hechas las importaciones de los módulos y librerías que vamos a necesitar, pasaremos a crear la interfaz de nuestro programa:
Como se ve, empezamos creando la clase de nuestra aplicación «App«, consistente solo (de momento) en una ventana, en cuyo interior, introducimos un display de fondo negro (creado con el método «ScrolledText«) destinado a ser donde se mostrará la información oculta de nuestro archivo de imagen, también mostraremos una pestaña (creada con «Label») en donde en su momento figurará el nombre del archivo cuya información se esté mostrando y un botón «btn_search» (creado con el método «Button» que tantas veces hemos visto) mediante el que, en su momento, haremos la búsqueda del archivo de imagen (que deberá ser de extensión «.jpg«). Efectivamente la ejecución de lo hecho hasta ahora, dará el siguiente resultado:
Ya tenemos nuestra interfaz creada, aunque de momento, esta no hace nada. Por ello, la siguiente fase será la de definir las funciones a través de las cuales, vamos a poder buscar el archivo cuya información queremos leer, para a continuación mostrar dicha información en el display creado. No obstante, antes de ello, vamos a ver, en el editor, el procedimiento «manual» para obtener los metadatos de una foto, usando «Pillow» y su módulo «ExifTags» para luego aplicarlo a nuestra aplicación:
Como se ve, empezamos abriendo nuestro archivo de imagen, usando la función «open()» almacenando la información de la misma, en la variable «image«, de la que, a su vez, procederemos a leer sus metadatos con el método «._getexif()» almacenando dichos datos en «exifdata«. Una vez que hemos obtenido nuestros metadatos, pasaremos a mostrarlos en pantalla en un formato que presente el nombre del campo («tag«) y su valor asociado («data«). Ello lo haremos iterando sobre cada uno de los elementos presentes en «exifdata«, decodificandolos, para luego mostrarlos en pantalla tal y como se muestra a continuación:
Una vez que conocemos el procedimiento para, extraer los metadatos de la imagen, solo tenemos que implementarlo en nuestra aplicación. Como hemos dicho antes, la aplicación permitirá (con «SEARCH FILE«) buscar y seleccionar el archivo cuyos a cuyos datos ocultos queremos acceder. Para ello, crearemos una primera función, a la que daremos el nombre de «open_file()«:
Como se ve, en esta función usamos «askopenfilename()» para abrir el navegador de nuestro sistema de archivos de modo que podamos seleccionar la imagen (que por defecto será de extensión «.jpg«) cuya información queremos extraer. La ruta a dicho archivo quedará almacenada en la variable «file» de modo que solo si el valor de esta no está vacío (lo que pasaría si cerráramos el navegador sin haber seleccionado ningún archivo)es decir «if self.file!=»»«, se guardará (en «filename«) el nombre (sin la ruta completa) del archivo, se mostrará en la etiqueta «file_label» el nombre de dicho archivo («self.file_label.configure(text=self.filename)«) y se ejecutará la función encargada de extraer y mostrar la información de la imagen. Dicha función tiene por nombre «extract_data()» y es la que mostramos a continuación:
La función (que tomará como argumento el nombre del aechivo seleccionado en el paso anterior) se iniciará realizando una limpieza del display («self.display.delete(‘1.0’,END)«). Tras ello, como vimos en el ejemplo anterior, procederá a abrir dicho archivo («image=Image.open(f)«) para, a continuación, extraer la información oculta que pueda tener. En este caso pueden suceder dos cosas: El primero de ellos es que el archivo abierto carezca de este tipo de información (con lo que el valor de «exifdata» será «None«) en cuyo caso se mostrará el mensaje «NO DATA» en el display («self.display.insert(END,’NO DATA’)«) .
La segunda posibilidad es que el archivo abierto si disponga de dicha información. En cuyo caso se aplicará el procedimiento para mostrar los campos («tags«) y su correspondientes valores («data«) siguiendo el procedimiento que vimos antes, con la salvedad de que, en este caso, vamos a hacer unas previsiones que no hicimos en el ejemplo, y es la que tiene que ver con la posibilidad de que al decodificar la información, nuestro programa se tope con algún carácter que no pueda mostrar en el display. Siendo este el motivo por el que utilizamos un «try» para la operación de mostrado de información en el display. De modo que si dicha acción no se pudiera llevar a cabo tal operación, usaremos «re.sub()» para sustituir dichos caracteres por un espacio en blanco.
Aunque a la hora de buscar el archivo cuya información queremos extraer, el formato que se mostrará por defecto es «.jpg» (ya que es el formato principal que soporta el extandard «EXIF«) cabe la posibilidad que se acabe seleccionando un archivo que no lo haga. en cuyo caso nuestra aplicación mostrará «ERROR» en el display:
Y con esto tendríamos creada nuestro propio visor de datos EXIF. Como se ve, se trata de un programa bien sencillo cuyo código integro podéis ver en el siguiente enlace:
https://github.com/antonioam82/Data_exctractor/blob/master/EXIF_data_viewer.py
Saludos.