~
~
:wq

Saturday 13 February 2010

Rectificar la fecha en las fotografías

english version - all spanish posts

Tengo una serie de scripts en bash que creé cuando me compré la primera cámara digital, en el 2003 o 2004, que me permiten clasificar las fotos por fechas. Extraen los metadatos del encabezamiento de las fotografías mediante el comando strings. A partir de la fecha que proporcionan los metadatos exif renombran cada fotografía como AAAMMDD_HHMMSS_#.jpg (el # indica el número de fotografía en caso de que varias tuvieran el mismo timestamp) y además guardan cada fotografía en un directorio llamado FOTOS/AAA/MM. De esta forma tengo todas las fotografías digitales ordenadas por fechas independientemente de la cámara usada.

Resulta que hoy al ejecutar el script para importar las fotos de dos de mis cámaras digitales me he dado cuenta de que las fotos de una de las cámaras tenían mal puesta la fecha. Se trata de una cámara que tiene mal la batería y se resetea a la configuración de origen cada vez que la recargo. Por error al volver a conectar la cámara me equivoqué y puse año 2009 en lugar de 2010. Unas 200 fotos se clasificarán mal si no lo remedio.

Editar directamente el texto ascii del encabezamiento de las fotografías (el que se obtiene con strings) no sirve para cambiar la fecha (lo he probado) por lo que con las herramientas bash habituales no me iba a ser posible editar las 200 fotos con el año mal puesto.

Después de un rápido «googleo» obtengo una prometedora sugerencia:

jhead es una herramienta de línea de comandos que de haberla conocido hace unos años me hubiera ahorrado los scripts de bash pero también toda la diversión que tuve con ellos al hacerlos. Permite no solo mostrar y manipular los metadatos exif de las imágenes sino manipular los ficheros de las fotos a partir de estos datos.

Os muestro como usar jhead para reparar la fecha de las fotos por si os pasa algo similar. En primer lugar lo instalamos (yo uso en el ordenador donde guardo las fotos Ubuntu 9.10):

aptitude update && aptitude install jhead

Editar las fotos para cambiar la fecha es tan sencillo como ejecutar el siguiente comando que se encarga de modificar la fecha de las fotos añadiendo un año a todas ellas. Con este comando he conseguido incrementar la fecha en un año en las 200 fotos de la tarjeta:

jhead -da2010:01:01-2009:01:01 *.jpg

jhead merece mucho la pena así que os recomiendo que os deis una vuelta por su manpage para ver todo lo que puede ofrecer (que es bastante).

Otro ejemplo que me gustaría comentaros es como jhead con un solo comando sustituye gran parte de la funcionalidad del script que uso para clasificar fotos. Vamos a renombrar una foto usando el timestamp de sus metadatos exif de modo que pase a llamarse AAAMMDD_HHMM.jpg:

~$ jhead -nf'%Y%m%d_%H%M%S' IMGP4890.JPG
IMGP4890.JPG --> 20100212_090624.jpg

Realmente sencillo.

Como homenaje a mi script que ha venido funcionando perfectamente desde el 2004 os lo muestro a continuación, ya que con jhead va a dejar de ser usado. Como podéis ver además de renombrar las fotos, como os he comentado al principio, el script las clasifica en directorios AAAA/MM y gestiona fotos con el mismo timestamp. El script es un poco enrevesado, revisándolo para este post me doy cuenta de que mi técnica de scripting afortunadamente ha mejorado mucho con el tiempo:

#! /bin/bash
# vim:ts=4:sw=4:et:ft=sh
# $Source: camara_scripts/RCS/fotos_script_testTEST.sh,v $
# <hmontoliu@yahoo.es>
# 2004-01-13

: ${DESTDIR:="$HOME/FOTOS/"}
echo "Utilizando directorio destino: $DESTDIR"
echo
echo "OK (Ctrl-C aborta)?"; read foo

shopt -s extglob # for improved file pattern matching
for imgname in *.+(jpg|JPG);
do
    newname="$(head "$imgname"|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /_/g; s/://g; s/$/.jpg/; p}'|uniq)"
    eval $(echo $newname | sed -n 's/^\([0-9]\{4\}\)\([0-9]\{2\}\).*/year=\1 month=\2/p')
    mkdir -p ${DESTDIR}/$year/$month
    cp -v --backup=numbered --suffix=- "${imgname}" "${DESTDIR}/$year/$month/$newname"
done

# lets rename the xxx.jpg.~#~ generated by cp backup to xxx-#-.jpg
for file in $(find $DESTDIR -regex '.*~[0-9]+~')
do
    safenewname="$(echo $file | sed 's/\(.*\).jpg.~\(.[^~]*\)~/\1-\2.jpg/')"
    if [ -f "$safenewname" ]; then
        mv -iv "$file" "$safenewname"
    else
        mv -v "$file" "$safenewname"
    fi
done

En fin, voy a dejar de usarlo, con jhead y rename (prename de perl) el nuevo script se quedará en solo un par de líneas.

0 comments:

Post a Comment