Poesía Binaria

Jugando con ImageMagick (IV): Automatizando procesos, creando animaciones

El cuarto post de la serie, anteriormente hablábamos de:

  1. Dimensiones, Captura, Color y Efectos
  2. Color (continuación) y Rotación
  3. Jugando con ImageMagick (III): Colecciones, texto, y unión de efectos

Ya que estamos hartos de ver lo que es capaz de hacer ImageMagick, ahora mezclemos esto con la potencia de la consola, y tendremos una de las herramientas más potentes jamás inventadas en cuanto a imagen digital se refiere.

Modificando imágenes en un directorio

Aunque podremos hacer cualquier tipo de modificación, tal y como hemos visto anteriormente, haremos un ejemplo en el que redimensionaremos todos los archivos de un directorio al 50% (muy útil si preparamos en un directorio muchos archivos directamente de una cámara digital para subir a Internet):

$ mogrify -resize 50% directorio/*

Con mogrify podemos hacer lo mismo que con convert, sólo que el fichero de origen y de destino es el mismo.

Aunque… ¿y si queremos guardar los archivos originales? Tendremos que hacer un pequeño script para convertir los archivos de un directorio y guardarlos en otro direcorio diferente; pero… y si son muchos ? Tenemos algunas posibilidades:

$ for f in test/*.jpg; do convert -monitor -resize 50% $f «test2/»${f##*/}; done

Si tenemos todos los archivos en el directorio test, queremos redimensionar al 50% y guardarlos en test2/ con el mismo nombre que tienen. ${f##*/} elimina el directorio del nombre del archivo, es lo mismo que la orden basename. Y con el parámetro -monitor veremos más o menos lo que está haciendo convert en cada momento.

Aunque, tal vez queramos un indicador de progreso para saber más o menos cuánto queda y cuántos archivos llevamos, lo podemos hacer con bc y Xdialog:

1
2
3
4
5
6
7
8
9
archivos=`ls test/*.jpg`;
total=`echo $archivos | wc -w`;
hecho=0;
for f in $archivos;
do
convert -resize 50% $f "test2/"${f##*/};
let hecho=$hecho+1;
echo "scale=0;$hecho*100/$total"|bc;
done | Xdialog --gauge "Progreso..." 10 100 0

En este ejemplo, separamos en variables los archivos a tratar y contamos el total de archivos a procesar. La variable hecho contará cuántos archivos ha convertido hasta el momento.

Luego en el bucle principal convertiremos los archivos e iremos incrementando la variable hecho en 1. Más adelante, con la ayuda de bc calculamos el porcentaje hecho. El bucle lo pasamos con una pipe a Xdialog, con su opción de gauge con lo que iremos indicando el proceso a medida que se vayan convirtiendo archivos.

Añadiendo un texto a todas las imágenes

Podemos, además, añadir un texto a todas las imágenes con un formato determinado para incluir el nombre de fichero, ancho, alto, la etiqueta de fichero, etc:

$ mogrify -gravity South -pointsize 20 -fill black -annotate ‘%f %b bytes» *

Con lo que anotaremos dentro de la imagen en color negro el nombre del archivo y el tamaño en bytes. Para esto tenemos algunas palabras clave como %f y %b en este enlace: Imagemagick.org (Identify -format).

Aunque tal vez queramos poner un texto diferente a cada foto. Imaginemos que tenemos muchos ficheros jpg y muchos ficheros txt. Los ficheros txt tienen el mismo nombre que los jpg y sólo varía la extensión; y queremos plasmar el texto de los txt en los ficheros jpg:

1
2
3
4
5
6
7
8
9
10
11
for f in *.jpg;
do
if [ -r ${f%.*}.txt ];
then
txt=`cat ${f%.*}.txt`;
else
txt="Mis guisos 2010";
fi;
echo $txt en $f;
mogrify -gravity North -pointsize 15 -fill white -annotate 0x0+10+10 "$txt" $f;
done

Esta vez, si encontramos el fichero de texto con el mismo nombre que la imagen, solo que con extension txt escribiremos ese texto en la parte superior de la imagen; pero si no, escribiremos «Mis guisos 2010» y así recorriendo todos los archivos jpg del directorio.

Una animación sencilla

Vamos a crear una transición entre dos imágenes. Y para el ejemplo, hemos utilizado estas dos imágenes:

$ convert -size 720×576 xc:black -gravity Center -fill white -pointsize 250 -font impact -draw ‘text 0 0 A’ a.jpg

$ convert -size 720×576 xc:black -gravity Center -fill white -pointsize 250 -font impact -draw ‘text 0 0 B’ b.jpg

Para realizar el fundido hacemos lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
n_imgs=30; # Número de imágenes
s=`echo "scale=2;100/$n_imgs" | bc` # Porcentaje de inremento de cada paso.
o=0;   # Visibilidad de la imagen B
d=100; # Visibilidad de la imagen A
f=0;   # Fotograma actual
while (( $f < 20 ));
do
convert -compose blend -set "option:compose:args" $o,$d a.jpg b.jpg -composite dest/anim_$f.jpg;
o=`echo "scale=2;$o+$s" | bc`;
d=`echo "scale=2;$d-$s" | bc`;
f=$(($f+1));
echo "Frame: $f O=$o D=$d";
done

Con esto se creará la secuencia de $n_imgs (que al principio le damos valor 30) imágenes en el directorio dest/; todas empezando por anim_.

Si queremos crear un gif animado con esto, podemos hacer lo siguiente:

$ convert dest/anim_{0..29}.jpg trans.gif

También podría interesarte....