Une carte postale en GIF animée

Voici enfin, après de trop longs mois d'attente, le premier jet du générateur de carte postale pour épileptiques. Pour commencer nous allons faire simple, et peut-être plus tard, nous songerons à améliorer la chose. D'accord, mais simple, dans ce contexte, c'est quoi ?

Simple, en parlant de gif89a, est un concept assez délicat à cerner, mais quand on parle de carte postale, en fait, il s'agit juste d'une image de fond fixe (quoique ?-) sur laquelle nous allons poser quatre (ou plus ?) images qui vont clignoter avec une cadence étrange, mais potentiellement hypnotique. Bref, un truc trop concept, quoi.

#!/bin/bash

LISTE=liste
BW=640 ; BH=480
MARGE=22
FRAMES=12

# ---------------------------------------------------------
#	faire le fond
FOND=crater.pgm
pgmcrater -number 172000 -height $BH -width $BW -gamma 2.5	|
	ppmquant -nofs 32 	> $FOND
# ---------------------------------------------------------
#	calculer les dimensions
PW=$(( (BW-(3*MARGE)) / 2 ))
PH=$(( (BH-(3*MARGE)) / 2 ))
echo "Dimensions des vignettes :" ${PW} ${PH}
# ---------------------------------------------------------

En premier, nous fixons quelques paramètres : un fichier contenant la liste des images, la taille de la gif89a finale, la marge qui sépare les vignettes, et le nombre de frames. En second, un étrange décor lunatique (construit avec pgmcrater, un cousin de ppmforge) est posé sur le fond de la carte. Pour suivre, nous calculons la taille des petites images que nous allons paster sur notre carte.

une surface lunatique

En avant !

Hop, le contexte est posé, passons aux choses actives. Il va d'abord falloir retailler nos images sources pour qu'elles rentrent dans le quart de la surface alloué, en tenant compte de la marge.

# ---------------------------------------------------------
#	retailler les N? images sources
nbre=0
for src in $(cat ${LISTE})
do
	resized=$(printf "/tmp/resized%02d.pnm" $nbre)
	newdim=" ${PW}x${PH}! "
	echo $src $newdim '==>' $resized
	convert -resize ${newdim} -posterize 32 ${src} ${resized}
	nbre=$(( nbre + 1 ))
done
echo hop, il y a $nbre images
# ---------------------------------------------------------

C'est une boucle tout à fait basique, qui va générer des miniatures adressables par un indice. Notez quand même un point important : il y a un ! à la fin du paramètre de l'option -resize de convert. Il va forcer le resize de convert à utiliser précisément cette géométrie là, au lieu de faire sa sauce avec l'aspect ratio.

Nous avons donc maintenant nos petites images, il ne reste plus qu'à les poser sur le carton lunaire. Ce qui nous conduit à deux boucles imbriquées. La première pour générer les $FRAME images, et la seconde pour choisir et placer les quatres petites images.

# ---------------------------------------------------------
#	generer et placer les nbre*FRAMES clones
for frame in $(seq 1 ${FRAMES})
do
	WORK=$(printf "/tmp/wrk%02d.pnm" ${frame})
	cp $FOND $WORK

	for foo in $(seq 1 4)
		do
		numero=$(( (frame+foo) % nbre ))
		s=$(printf "/tmp/resized%02d.pnm" ${numero})

		case $foo in
		1) X=$MARGE; Y=$MARGE ;;
		2) X=$(( BW/2 + MARGE/2)); Y=$MARGE ;;
		3) X=$MARGE; Y=$(( BH/2 + MARGE/2 )) ;;
		4) X=$(( BW/2 + MARGE/2 )); Y=$(( BH/2 + MARGE/2 )) ;;
		esac

		pnmpaste -replace $s $X $Y $WORK > _$$.tga
		mv _$$.tga $WORK
		
		done

done
# ---------------------------------------------------------

La boucle externe est classique : for foo in $(seq 1 $FRAMES) pour fabriquer le nombre d'images demandé au début du script. La seconde l'est moins, pour deux raisons :

  1. comment choisir quelle vignette poker, ce qui est fait par la ligne numero=$(( (frame+foo) % nbre )), qui est un des points critiques pour la virulence du clignotage. C'est aussi ici que votre créativité pourra s'exprimer. Vous pouvez, entre autres choix, la remplacer par numero=$(( RANDOM % nbre )) et constater que ce n'est plus tout à fait pareil...
  2. comment déterminer où la placer, et c'est un case/esac contenant de savants calculs de coordonnées qui s'en charge.

Et pour terminer ce bijou, un petit coup de convert pour générer la gif89a que voici, que voilà :

et hop, une carte postale qui clignote !

Voilà, j'espère que ça vous a inspiré pour diffuser vos photos de vacances, et je vous propose de nous revoir bientôt pour la suite.