Robitex's Blog

Ideas in the web

Impaginare un album di foto con LaTeX


La sfida

Ieri un collega mi ha chiesto come realizzare un album fotografico includendo circa 200 immagini nel formato jpeg, con quattro foto per pagina ciascuna con la propria didascalia di numerazione.

Il problema è interessante perché occorre scegliere gli strumenti informatici più idonei e sperimentare ottimizzazioni nel caso in cui servisse spesso elaborare documenti simili.

Gli strumenti

Abbiamo scartato quasi subito di lavorare con un word processor, sia perché volevamo una soluzione automatica, sia perché avevamo dubbi sulle capacità di gestire file di grandi dimensioni da parte di questo tipo di programmi.
Di conseguenza abbiamo escluso anche la soluzione con AutoCAD con l’impiego dello spazio carta. Avremo dovuto infatti inserire riferimenti raster e didascalie in modo troppo complicato e manuale.

Rimaneva di addomesticare la questione con LaTeX…

La battaglia ha inizio

Per prima cosa abbiamo copiato in una directory locale le foto, i cui file apparivano nominati sequenzialmente nel formato “DSC_0000”, come si può notare nell’immagine sottostante.

La directory delle foto aperta in Explorer

In un foglio di calcolo (OpenOffice.org Calc), grazie alla facilità con cui è possibile generare le serie (ricopia in basso), ho riempito una colonna dei numeri da 1 a 176. A fianco della prima cella ho inserito la seguente formula (anch’essa ricopiata in basso) che genera una stringa che rappresenta il nome del file nel formato richiesto, dato come argomento di una macro chiamata \foto (il foglio di calcolo avrebbe generato con poca fatica automaticamente e direttamente il corpo del sorgente LaTeX):

=CONCATENA("\foto{DSC_";TESTO(A1;"0000");"}")

Se la cella A1 contenesse il valore 122, la formula fornirebbe la stringa “\foto{DSC_0122}”. La funzione CONCATENA non fa altro che restituire un unica stringa a partire dai vari argomenti stringa separati da un punto e virgola, mentre la funzione TESTO trasforma un numero in una stringa nel formato specificato (in questo caso le quattro cifre fisse con zeri di riempimento).

A questo punto ho cancellato una serie di righe corrispondenti a foto che non avrebbero dovuto essere incluse perché non significative poi ho copiato l’area della seconda colonna e l’ho direttamente incollata nell’editor di testo, che a questo punto mostrava un sorgente di questo tipo:

\documentclass[a4paper,11pt,landscape]{report}
\usepackage{calc}
\usepackage{graphicx}
\usepackage[top=60pt,bottom=20pt,right=30pt,left=30pt]{geometry}

\pagestyle{empty}

\begin{document}
\centering
\twocolumn

\foto{DSC_0001}
\foto{DSC_0002}
\foto{DSC_0003}
\foto{DSC_0004}
\foto{DSC_0005}
\foto{DSC_0006}
% ecc ecc
\end{document}

Non rimaneva che dare la giusta definizione della macro \foto, che molto semplicemente prende l’argomento come il nome del file jpg da includere e come testo didascalico da posizionare al di sotto della foto:

\newcommand{\foto}[1]{%
\includegraphics[width=\columnwidth-60pt]{#1}

Foto #1\bigskip

}

Evoluzione della specie

Notando che la compilazione del sorgente richiedeva un tempo abbastanza lungo abbiamo inserito dopo le prime quattro foto il comando \end{document} lasciando inalterato il resto del documento. Ridotto in questo modo il documento ad una sola pagina, è stato rapidissimo settare per tentativi i giusti parametri dimensionali dei margini di pagina e la larghezza delle foto, per tornare poi all’inclusione totale cancellando il comando di chisura dell’ambiente document (il motore tipografico di LaTeX ignora qualsiasi cosa compaia dopo \end{document}).

Ottenuto il pdf finale, abbiamo provveduto a spedire il file alla stampante, ben contenta di ridestarsi dal suo torpore, ma come sempre se si tratta di linguaggio, ulteriori sviluppi del codice ci attendevano, e pure a lavoro finito.

La domanda è: e se avessimo voluto una didascalia con il semplice numero della foto e non il nome del file?

La risposta è: ridefinendo il comando \foto per esempio impostando la macro per ricevere il numero della foto da cui ricostruire il nome del file:

Per prima cosa definiamo un contatore ed una macro che imposta una seconda macro con il prefisso del nome dei file. Nel nostro caso imposteremo “DSC_”, così da poter gestire diversi valori assegnati di solito dal software della macchina fotografica digitale.

Aggiungiamo poi una serie di \if annidati per produrre il formato a quattro cifre a partire dal numero della file:

\newcount\filenum
\newcommand{\fileprefix}[1]{\def\myfileprefix{#1}}

\newcommand{\foto}[1]{%
\filenum=#1

\ifnum\filenum<10
  \def\myfilenumber{000\number\filenum}
\else
  \ifnum\filenum<100
    \def\myfilenumber{00\number\filenum}
  \else
     \ifnum\filenum<1000
        \def\myfilenumber{0\number\filenum}
     \fi
  \fi
\fi

\includegraphics[width=\columnwidth-60pt]{\myfileprefix\myfilenumber}

Foto n. #1\bigskip

}

Il corpo del sorgente si modificherà in:

\begin{document}
\centering
\twocolumn

% settaggio del prefisso del nome file:
\fileprefix{DSC_}

% inclusione delle foto
\foto{1}
\foto{2}
\foto{3}
\foto{4}
\foto{5}
\foto{6}
% ecc ecc
\end{document}

La domanda è: perché passare da un foglio di calcolo per generare il codice?

La risposta è: giusta osservazione, basta indicare solo il primo e l’ultimo numero della foto e LaTeX farà il resto:

A livello d’implementazione del nuovo comando \foto, occorre inserire un ciclo che, per ogni numero nell’intervallo specificato, inserisca la foto. Dal punto di vista sintattico invece, prevediamo di definire l’intervallo specificandone gli estremi all’interno di parentesi tonde e separati dal simbolo -> (utilizzeremo quindi la tecnica degli argomenti delimitati di TeX).

Ecco il listato del sorgente completo (abbiamo inserito macro con il carattere @ nel nome per renderle private):

\documentclass[a4paper,11pt,landscape]{report}
\usepackage{calc}
\usepackage{graphicx}
\usepackage[top=60pt,bottom=20pt,right=30pt,left=30pt]{geometry}

\makeatletter
\newcount\foto@numi
\newcount\foto@numf

\def\fileprefix#1{\def\file@prefix{#1}}

\def\insert@foto{%
\ifnum\foto@numi<10
  \def\file@num{000\number\foto@numi}
\else
  \ifnum\foto@numi<100
    \def\file@num{00\number\foto@numi}
  \else
     \ifnum\foto@numi<1000
        \def\file@num{0\number\foto@numi}
     \fi
  \fi
\fi

\includegraphics[width=\columnwidth-60pt]{\file@prefix\file@num}

Foto n. #1\bigskip
\advance\foto@numi by 1
}

\def\foto(#1->#2){%
   \foto@numi=#1
   \foto@numf=#2
   \advance\foto@numf by 1
   \loop
   \insert@foto
   \ifnum\foto@numi<\foto@numf
   \repeat
}
\makeatother

\pagestyle{empty}

\begin{document}
\centering
\twocolumn

\fileprefix{DSC_}
\foto(1->35)
\foto(38->48)
\foto(50->81)
\foto(83->122)
\foto(124->148)
\foto(152->157)
\foto(163->176)
\end{document}

Si può fare ancora di più, prevedendo una sintassi per l’esclusione di paricolari foto. Un solo comando che la implementasse basterebbe per definire l’intero album di foto!
Nel nostro caso potrebbe essere questo:

\foto{1->176 except 36,37,49,82,123,149->151,158->162}

Conclusioni

Il collega non aveva mai prima d’ora visto all’opera LaTeX. Forse è utile riflettere sulle impressioni di un assolutamente nuovo utente. Riporto solo una frase: “voglio imparare questo sistema!!” ha detto, e speriamo che l’ho faccia veramente.

Per quanto riguarda invece il giudizio sull’efficienza e l’efficacia con cui è stato possibile risolvere il problema dell’album fotografico con LaTeX, la mia opinione come vi immaginerete è molto positiva: precisione del posizionamento delle foto, facilità di regolazione dei parametri e separazione tra file jpeg e sorgente, solo benefici specifici di questo motore tipografico asincrono. Rimango in attesa della vostra opinione se vorrete affrontare lo stesso problema confrontando diversi strumenti software.

Alla prossima. Ciao.

2 risposte a “Impaginare un album di foto con LaTeX

  1. Pietro 11/01/2011 alle 15:40

    ciao
    sono un frequentatore del forum di Guit ed un curioso del tuo blog.
    Mi permetto di suggerire una semplice implementazione del tuo codice \insertimage in ambiente linux:

    #/bin/bash
    for i in /home/pietro/foto/bellissimagiornata/*
    do
    echo ‘\insertimage{‘$i’}’ >> album.tex
    done

    In questo modo non è necessario che il basename dei file sia lo stesso per tutti, né si deve ricorrere al sempre amato foglio di calcolo.
    Saluti
    Pietro

    • robitex 11/01/2011 alle 16:11

      Bel suggerimento, grazie Pietro.
      Anche se l’album di foto è stato composto sotto Win XP (si trattava di una relazione dell’ufficio dove i pc sono tutti targati MS😦 ), l’idea si può ugualmente impiegare o con un file batch o con uno script Lua.
      Grazie.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: