You are here

Applicare gli stessi comandi a un insieme di immagini (Gimp batch) e farci un PDF

Per modificare le immagini io uso Gimp, che è un software libero di livello molto alto e adatto ad una molteplicità di usi, dai più semplici a quelli più professionali. Ho visto fare cose incredibili con Gimp da un'artista (Federica Vivarelli), durante un corso rivolto ad una scolaresta in occasone del Linuxday 2012 a Grosseto (vedi video del corso): sono rimasto a bocca aperta, in anni e anni che uso Gimp non sono mai arrivato a livello così alti.

Per vari motivi (legati soprattutto alla pubblicazione di immagini sul web), a volte mi è capitato di dover applicare lo stesso insieme di comandi ad una enorme quantità di immagini. So per esperienza che farlo a mano porta via un sacco di tempo (anche una giornata), è stancante ed espone ad errori. Per tale ragione, ho imparato ad automatizzare l'esecuzione di operazioni ripetitive.

Per piccole operazioni di conversione (o di ridimensionamento immagini) non è necessario Gimp, basta ad esempio un comando come il seguente per convertire tutti i files png nella cartella corrente in file jpg:

mogrify -format jpg *.png

In alternativa, un piccolo script analogo al comando precedente, che provvede alla conversione dei png in jpg sia nella cartella corrente, sia in tutte le sottocartelle, che non fa uso di mogrify ma di avconv, e che provvede anche ad eliminare i file jpg dopo la conversione, è il seguente:

#!/bin/bash
find . -type f -name '*.png' -print0 | xargs -0 -I {} avconv -i {} {}.jpg
find . -type f -name '*.png' -print0 | xargs -0 -I {} rm -f {}

Per operazioni più complesse che invece richiedono Gimp, il da farsi può essere così sintetizzato: basta creare uno script-fu e dare un comando da terminale. Tutto qua, ma adesso vediamolo in pratica.

Per l'appunto, oggi ho bisogno di applicare la funzione "autoritaglia immagine" ad alcune centinaia di immagini. Nella cartella di Gimp nascosta nella home, c'è una sottocartella scripts, nella quale ho creato un file di testo "autoritaglio.scm" (l'estensione "scm" è quella da utilizzare): nel mio caso, il percorso è quindi /home/francesco/.gimp-2.8/scripts/autoritaglio.scm

Ecco il contenuto del file:

(define (autoritaglio filename)
   (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
          (drawable (car (gimp-image-get-active-layer image))))
     (plug-in-autocrop RUN-NONINTERACTIVE image drawable)
     (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
     (gimp-image-delete image)))

Ho evidenziato in grassetto il comando di Gimp per l'autoritaglio delle immagini. La lista dei comandi disponibili e dei loro parametri è disponibile nel "Navigatore di procedure" sotto il menù "Aiuto" di Gimp. Questo semplice script-fu di nome "autoritaglio" non fa altro che aprire il file che gli passo come parametro in maniera non-interattiva e senza interfaccia grafica, applica la funzione autoritaglio, salva il file sovrascrivendolo e infine lo chiude.

Per applicare questo script-fu su un singolo file, che per esempio posso chiamare "foo.png", non devo far altro che dare da terminale:

gimp -i -b '(autoritaglio "foo.png")' -b '(gimp-quit 0)'

Per applicare, con un solo comando, lo stesso script su tutti i file png che ho nella cartella corrente e in tutte le sottocartelle, do:

find . -name "*.png" -exec echo {} \; -exec gimp -i -b '(autoritaglio "{}")' -b '(gimp-quit 0)' \;

Mentre Gimp fa il suo lavoro, che può durare anche a lungo a seconda della quantità di immagini, mi rilasso e faccio altro :)

Quando le immagini sono pronte, voglio mettere quelle presenti in ciascuna directory in un unico pdf in formato A4, pronto per la stampa, con due immagini per pagina. Mi posiziono in una directory e do il comando:

ls *.png -1 | awk '{printf("%s%s%s\n","\"",$0,"\"")}' | sort -n | tr '\n' ' ' | sed 's/$/\ mydoc.pdf/' | xargs montage -tile 1x2 -geometry +50+50 -frame 5 -title 'Titolo'

Questo comando è in realtà una pila di comandi, da personalizzare in base alle proprie esigenze. Tradotto: «Elenca tutti i file con estensione png della cartella corrente, aggiungi i doppi apici all'inizio e alla fine del nome di ciascun file (in modo da trattare correttamente i file che contengono spazi nel nome), ordina l'elenco dei file in base al nome (in modo che le immagini siano trattate nell'ordine corretto), sostituisci ogni "a capo" con uno spazio (in modo da avere un'unica stringa), aggiungi alla fine della stringa il nome del file di output (mydoc.pdf), infine esegui il comando "montage" (che serve per creare il pdf con le immagini) con i parametri da me specificati (due immagini per pagina, con margini di 50px, bordi di 5px e un titolo in cima ad ogni pagina) e passadogli la stringa precedentemente creata (contenente l'elenco delle immagini di input e il nome del file di output)».

Non è finita qui. Il pdf che avrò ottenuto avrà dimensioni arbitrarie, almeno nel mio caso sarà ben visualizzato da Evince ma non da Adobe Reader (non so perché), voglio farlo diventare un A4 e soprattutto un pdf standard ben supportato da ogni visualizzatore. Semplicemente procedo a stamparlo da Evince su PDF tramite cups-pdf selezionando A4 come formato della carta e scegliendo l'opzione di "ridimensionare e centrare automaticamente". Con questo metodo, otterrò un nuovo pdf che sarà anche ottimizzato rispetto al pdf originariamente creato da montage :)

Buono scripting a tutti,
Francesco Galgani

 

Classificazione: