Retourner automatiquement les photos avec Convert et les données Exif
Par Julien Vehent le samedi, juin 13 2009, 22:06 - Debian - Lien permanent
Retour de Chine et de week-end festivalier. Résultat: plusieurs milliers de photos, dont une bonne partie en Portrait, et le reste en paysage.
Du Portrait, il y en a deux types, car Mademoiselle et moi-même ne tenons pas l'appareil de la même facon. Du coup, quand il faut visionner tout cela, et retourner les photos, c'est un peu le bazard.

Surtout que Gwenview, la visionneuse que j'utilise sous KDE, retourne les photos automatiquement lors du visionnage, mais ne modifie pas le fichier original.
D'oú la certitude que l'info d'orientation doit bien se trouver quelque part ! En fait, j'ai découvert que le Nikon D50 (toujours de la miss) est équipé d'un gyroscope et que ce dernier conserve l'orientation de l'appareil dans un champ Exif. La norme prévoit d'ailleurs le stockage de cette info dans le champ 0x0112, communément appelé Orientation :
Tag No. Tag Name Format CompoNosource
0x0112 Orientation unsigned short 1
Desc.
------------------------------------------------
Value 0th Row 0th Column
1 top left side
2 top right side
3 bottom right side
4 bottom left side
5 left side top
6 right side top
7 right side bottom
8 left side bottom
Une fois l'info trouvée, ya plus qu'a scripter, comme dirait l'autre ! Exiv2 pour la partie Exif, Convert pour la partie Rotate, et le tour est joué. Le script ci-dessous est simple: il regarde l'orientation (gauche ou droite seulement), tourne la photo ci-besoin et update le champ exif.
#! /bin/sh
echo
echo"picture rotation in progress"
echo
# create a new folder
mkdir rotated
# get the .JPG extensions and rename them in .jpg
#
LISTJPG=`ls -l |grep JPG|tail -n 1|awk {'print $8'}`
if [$LISTJPG ]
then
for i in *.JPG
do
NEWNAME=`ls |grep"$i"|cut -d "." -f1`
mv"$i""$NEWNAME.jpg"
echo"changing JPG to jpg for $i"
done
fi
# is there any .jpg to process in this folder ?
#
LISTJPG=`ls -l |grep jpg|tail -n 1|awk {'print $8'}`
if [$LISTJPG ]
then
for i in *.jpg
do
ORIENTATION=`exiv2 pr -p t $i |grep Orientation|awk {'print $4 $5'}`
echo"$i has orientation $ORIENTATION"
if ["$ORIENTATION"="left,bottom" ]
then
convert $i -rotate -90 rotated/$i
exiv2 -M "set Exif.Image.Orientation Short 1" rotated/$i
elif ["$ORIENTATION"="right,top" ]
then
convert $i -rotate 90 rotated/$i
exiv2 -M "set Exif.Image.Orientation Short 1" rotated/$i
else
cp"$i" rotated/
fi
done
fi

Commentaires
Merci pour le tuyau (attention : il manque des espaces sur plusieurs lignes de code ! Notamment après les "["). Pour la partie haute du script, rename est notre ami. Pour la détection de la rotation, il faut forcer la langue anglaise, sinon le package de langue de exiv va faire des siennes. J'ai eu des warnings bizarroïdes, virés avec 2>/dev/null. Et enfin, il faut bien greper Image.Orientation : il peut exister aussi Thumbnail.Orientation, et le script merdouille lamentablement dans ce cas...
for i in *.jpg
do
ORIENTATION=`LANG=en exiv2 pr -p t $i 2>/dev/null |grep Image.Orientation|awk {'print $4 $5'}`
echo "$i has orientation $ORIENTATION"
if [ "$ORIENTATION" = "left,bottom" ]
then
convert $i -rotate -90 rotated/$i
LANG=en exiv2 -M "set Exif.Image.Orientation Short 1 2>/dev/null" rotated/$i
elif [ "$ORIENTATION" = "right,top" ]
then
convert $i -rotate 90 rotated/$i
LANG=en exiv2 -M "set Exif.Image.Orientation Short 1 2>/dev/null" rotated/$i
else
cp "$i" rotated/
fi
done