miércoles, 30 de septiembre de 2009

HAL también escanea

No hace mucho ;-) dejamos a nuestro HAL entregado a sus tareas rutinarias ---el sueño también forma parte de ellas---, mientras nosotros nos tomábamos unas largas vacaciones. Y es que la inmersión realizada el año pasado fue tan acelerada que había que salir a flote como fuera. Mejor retomar el hilo con algo más de moderación y de iniciar nuevas conversaciones sólo cuando la ocasión lo pida o lo permita, es decir, sin horario ni planificación prefijada.

Una ocasión de este tipo le ha surgido al autor hace poco, y lo que de ella se sigue será útil para completar lo que ya vimos sobre repeticiones y bucles, aparte de para seguir demostrando con un caso real la multiplicidad de posibles aplicaciones de la lengua de HAL a nuestras tareas habituales.

Se recordará que la instrucción for nos sirvió entonces para ordenar a HAL que recorriese las líneas de un fichero y aplicase un mismo bloque de instrucciones a cada una de ellas. En la siguiente conversación veremos un uso semejante, probablemente más frecuente, de for, en el que las unidades textuales recorridas no son líneas de ficheros, sino nombres de fichero.

Aunque ésta es probablemente la forma más frecuente de realizar tareas repetitivas en la lengua de HAL, es decir, la de recorrer unidades textuales (sean, por ejemplo, las líneas de un fichero o los nombres de una serie de nombres de fichero), hay situaciones en que es más práctico, más fácil o, simplemente, más del gusto del usuario, repetir una serie de instrucciones un número determinado de veces. Y esto es justo lo que vamos a tratar de conseguir en la conversación que hoy iniciamos.

Dedicaremos este primer artículo a especificar la tarea que motivó la conversación y la forma en que puede diseñarse un procedimiento para ejecutarla. De paso, aprenderemos a escanear un documento sin salir de la consola, cosa que quizá muchos, acostumbrados a las aplicaciones gráficas, consideren poco menos que magia negra. Aunque ---todo hay que decirlo--- esta clase de sortilegios, lanzados desde la negra interfaz de la consola, es algo a lo que deberíamos ya estar acostumbrados a estas alturas de nuestras charlas.

La tarea que nos proponemos realizar es la siguiente. Contamos con un libro voluminoso que contiene la obra completa de obras para laúd solo del gran compositor renacentista John Dowland y necesitamos extraer de él unas cuantas piezas que quepan fácil y livianamente en nuestro atril. Nos interesa, en particular, generar un fichero pdf para cada una de esas piezas.

Resulta evidente que aquí nos enfrentamos a dos problemas diferentes, en primer lugar, el de escanear las correspondientes páginas del libro y, en segundo lugar, el de generar tantos pdfs como obras queremos extraer. Nótese, en especial, que puede haber obras que consten de una sola página y obras que consten de varias páginas, y que lo que pretendemos es producir un pdf por obra y no por página.

Además, y puesto que sabemos ---el autor lo sabe, el lector debe asumirlo como presupuesto--- que HAL es capaz generar eficazmente un pdf por obra si cuenta con un pdf por página, el primero de los problemas se bifurca, a su vez, en otros dos, el del escaneo propiamente dicho y el de la conversión en pdf del resultado de dicho escaneo.

Hay que añadir, además, que, a causa tanto del tamaño del libro como de sus características físicas, será necesario retocar la imagen inicialmente escaneada para que el pdf que resulte de su conversión se adecue mejor a su posterior impresión en papel A4.

Por tanto, nuestro problema completo constará, al menos, de las siguientes partes:

  1. Escanear las páginas del libro.

  2. Retocar el resultado como convenga.

  3. Convertir los ficheros resultantes en pdfs.

  4. Unir en un único pdf los ficheros de cada página, cuando la obra conste de varias.


Podemos ser todavía más precisos si tenemos en cuenta las especificidades del proceso de escaneo. En concreto, será necesario producir una imagen donde se tengan en cuenta sólo las diferencias entre blanco y negro (lo que se llama modo Lineart) y no los tonos de grises o las divergencias de colores, que en nuestro libro no existen. Esto producirá un formato de imagen pbm. Este tipo de fichero es que el que tendremos que retocar y convertir a pdf, antes de pasar a la concatenación de los diversos pdfs. Podríamos, pues, plantear un esquema de las operaciones implicadas y los datos que se procesan dentro de ellas [Por cada página se presenta la serie de procesos por la que atravesará y los formatos de ficheros resultantes]:

/-------\ pbm /-------\ pbm /----------\ pdf
P1->|escaneo|---->|retoque|---->|conversión|-----\
\-------/ \-------/ \----------/ |
|
/-------\ pbm /-------\ pbm /----------\ pdf | /-------------\
P2->|escaneo|---->|retoque|---->|conversión|-----|--->|concatenación|->pdf
\-------/ \-------/ \----------/ | \-------------/
|
/-------\ pbm /-------\ pbm /----------\ pdf |
Pn->|escaneo|---->|retoque|---->|conversión|-----/
\-------/ \-------/ \----------/

Una inmersión en las interioridades del sistema de paquetes de HAL y de las páginas del manual ---cosas, ambas, que ya tratamos en la primera parte de esta serie--- nos permite descubrir de qué posibles herramientas disponemos. En concreto [señaladas bajo cada caja]:

/-------\ pbm /-------\ pbm /----------\ pdf /-------------\
Pn->|escaneo|---->|retoque|---->|conversión|---->|concatenación|->pdf
\-------/ \-------/ \----------/ \-------------/
scanimage unpaper convert pdftk

Cada una de estas herramientas ---o, si se quiere, de estos ayudantes de HAL--- forma parte de un paquete. A saber, en sistemas basados en Debian:

scanimage
paquete sane-utils

unpaper
paquete unpaper

convert
paquete imagemagick

pdftk
paquete pdftk


En los próximos días nos las apañaremos para construir un par de guiones que generen pdfs a partir de las páginas escaneadas y que procedan, en su caso, a su posterior concatenación. Será con la venia de estos bien predispuestos ayudantes.

HAL está esperando :-)

1 comentario:

  1. He modificado mi idea inicial sobre la "conversación" que se inicia con esta entrada.

    Pretendía en un principio aludir a while y a expansión aritmética. Pero el problema original no requiere estos elementos del lenguaje. Tratar de modificar la solución que propondré (si no la única posible, sí, al menos, relativamente natural) con el fin de introducir artificialmente nuevos constructos lingüísticos no compensa.

    ResponderEliminar