Escanear un álbum de fotografías con un script desde la línea de comandos

on

Es evidente que hay varias interfaces gráficas para escanear fotos, que brindan numerosas opciones. Pero cuando la cantidad de fotos a escanear es grande y no tenemos un escáner que tenga un  alimentador automático de hojas, el asunto se pone bravo. En general hay que hacer un clic para escanear, otro clic quizás en la otra punta de la ventana para guardar... lleva tiempo. En fin, una buena excusa para usar la línea de comandos.


Este es un aporte de Rubén, convirtiéndose así en uno de los ganadores de nuestra competencia semanal: "Compartí lo que sabés sobre Linux". ¡Felicitaciones Rubén!

Leía los artículos sobre Procesamiento de imágenes por lote con GIMP y Cómo manipular imágenes desde el terminal, justo el día que mi amigo Huguito me pidió las fotos (que había perdido) de un viaje que hicimos en 1989... (4 rollos de 36 fotos! y en papel, claro :-) . Me hizo recordar este tip para escanear fotografías que tenía olvidado.

La idea es usar un script para hacerlo lo mas rápido posible:

1.- Poner una foto en el escáner
2.- Presionar alguna tecla para escanear
3.- Repetir el procedimiento, salvo que la tecla presionada sea por ejemplo una 'n' para salir
4.- Las fotos quedarán guardadas y numeradas en un subdirectorio preestablecido.


¿Que comando?

El comando 'mágico' es scanimage que forma parte de SANE. SANE es una API que proporciona un acceso estandarizado a cualquier dispositivo escáner de imágenes. La API de Sane es de dominio público y su código fuente está disponible bajo la Licencia Pública General GNU.

La instalación es sencilla. Cada distribución trae sus paquetes. Para Ubuntu (o sus derivados), sobra con usar synaptic e instalar sane y sane-utils.


¿Cómo se usa ?

Cómo siempre lo mejor es escribir en una terminal 'man scanimage'. No obstante, haremos un resumen de las opciones que usaremos.

Abrimos una terminal y ejecutamos scanimage -L para ver los dispositivos disponibles:

scanimage -L

En mi caso, devuelve:

device `xerox_mfp:libusb:001:005' is a SAMSUNG ORION multi-function peripheral

Este es el resultado que me dio con mi multifunción Samsung SCX-4200. Si tienen una multifunción y no encuentra el dispositivo, asegúrense que no esté activa la impresora, por ejemplo con una impresión pendiente.

El valor 'xerox_mfp:libusb:001:003' nos sirve para indicarle al comando scanimage qué dispositivo usar a traves de la opcion -d. Si sólo hay un escáner conectado no es necesaria esta opción.

Cuando el comando scanimage escanea, envía la imagen resultante a la salida estándar en formato pnm o tiff. Entonces para escanear redirigimos la salida a un archivo. Y si queremos ver qué mensajes va dando el comando le agregamos la opción -v. Si además queremos ver el porcentaje de progreso de la operación agregamos la opción -p.

scanimage  -v -p > imagen.tiff

scanimage: scanning image of size 1284x1734 pixels at 24 bits/pixel
scanimage: acquiring RGB frame
scanimage: min/max graylevel value = 69/255
scanimage: read 6679368 bytes in total
Progress: 13.8%

¿Qué nos dará si hacemos scanimage --help? Parece obvio, da una ayuda sobre el comando. Pero este comando tiene una particularidad. Al final de la ayuda genérica del comando agrega los parámetros específicos que acepta tu escáner.

scanimage --help

Usage: scanimage [OPTION]...

bla, bla....

Options specific to device `xerox_mfp:libusb:001:005':

estándar:
--resolution 75|100|150|200|300|600dpi [150]
Sets the resolution of the scanned image.
--mode Lineart|Halftone|Gray|Color [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--highlight 30..70% (in steps of 10) [inactive]
Select minimum-brightness to get a white point
--source Flatbed|ADF|Auto [Flatbed]
Selects the scan source (such as a document-feeder).
Geometry:
-l 0..215.9mm (in steps of 1) [0]
Top-left x position of scan area.
-t 0..297.18mm (in steps of 1) [0]
Top-left y position of scan area.
-x 0..215.9mm (in steps of 1) [215.9]
Width of scan-area.
-y 0..297.18mm (in steps of 1) [297.18]
Height of scan-area.

Type ``scanimage --help -d DEVICE'' to get list of all options for DEVICE.

List of available devices:

xerox_mfp:libusb:001:005

De aquí podemos elegir las opciones con los valores que podemos usar.

Ejemplo:

Resolución

--resolution 150

Modo

--mode Color

Ahora la geometría. Esto es muy útil porque le podemos decir al escáner que sólo extraiga la imagen de un sector (donde pondremos la fotografía) , y nos ahorramos el tiempo de escanear el resto de la superficie que ademas deberíamos cortar luego con algún editor de grafícos como el Gimp.

-l 0 comienza a escanear en forma horizontal a partir de los 0 mm de la esquina superior izquierda del escáner

-t 0 comienza a escanear en forma vertical a partir de los 0 mm de la esquina superior izquierda del escáner

Observen que elegí poner la fotografía en la esquina del escáner [coordenadas (0,0)], ya que es mas fácil de colocar. En mi escáner (tamaño A4) l puede ir de 0 a 215.9 y t de 0 a 297.18.

Ancho y Alto de la fotografía. En mi caso las fotos son de 13x18cm:

-x 180 ancho

-y 130 alto

Por lo tanto escaneará sólo la parte donde pusimos nuestra foto. Claro si coincidimos en lo que es la izquierda, la derecha, el ancho, el alto, el arriba el abajo. Es que dependerá de cómo miren su escáner. Sugiero probar las coordenadas y ajustarlas a sus necesidades.

Un ejemplo del comando podría ser:

scanimage -d xerox_mfp:libusb:001:003  -p  --mode Color  --resolution 150  -l 0   -t 0  -x 180  -y 130  > imagen.pnm

Con estas opciones, ya podríamos armar nuestro script.




Pero antes...

El tiff o el pnm son formatos sin compresión, por lo que nuestras fotos ocuparán un espacio de disco enorme. Aquí es donde viene el comando convert de ImageMagick que se explica en Cómo manipular imágenes desde el terminal.

Si obtenemos del escáner una imagen.pnm podemos convertirla a jpg:

convert imagen.pnm imagen.jpg

Pero antes de hacerlo, otro truco:

La imagen.pnm ocupa mucho espacio y deberíamos borrarla luego de obtener nuestra imagen.jpg. Hay una opción para el comando convert para que en vez de tomar un archivo del disco convierta directamente la entrada estándar. Esto se logra con un guión - en lugar del archivo:

convert  - imagen.jpg

Como scanimage entrega la imagen escaneada a la salida estandar, hacemos una "tubería" y nos ahorramos el tiempo de procesamiento que lleva escribir y luego borrar el archivo imagen.pnm del disco.

scanimage -d xerox_mfp:libusb:001:003  -p  --mode Color  --resolution 150  -l 0   -t 0  -x 180  -y 130  | convert  -  imagen.jpg


Ahora sí, el script...

Escribimos el siguiente código en un archivo que llamaremos scan-album.sh y le damos permiso de ejecución. Cuando lo ejecutemos creará un subdirectorio donde estarán nuestras fotos escaneadas. Recuerden modificar los valores de los parámetros a sus necesidades.

No dejen de leer algunas sugerencias que hay luego del script.

#!/bin/bash
# Datos para las opciones

VERBOSE=""    # ver msg de estado:  "" es no  ;   "-v" es si
PROGRESS="-p"      # mostrar progreso "" es no ; "-p" es si

# Los parametros que siguen son  dados por scanimage --help para su escáner
#Dispositivo: Si hay un solo escáner no haca falta, poner DEV=""
#DEV="xerox_mfp:libusb:001:003" 

DEV=""
MODE="--mode Color"
RESOLUCION="--resolution 600dpi"

#geometria, ej foto de 130x180 mm
#ubicacion en el scaner del vertice superior izq

x0=0      
y0=0
ancho=180
alto=130

#opciones:

L="-l $x0" 
T="-t $y0"
ANCHO="-x $ancho"
ALTO="-y $alto"

# todos los parametros juntos:

PARAMETROS=" $DEV $VERBOSE $PROGRESS $MODE $RESOLUCION  $L $T $ANCHO $ALTO"

# Nombre del album . Crea un subdirectorio con su nombre:

ALBUM="Vacaciones_1989"

# Por seguridad, no hago nada si ya existe el directorio

mkdir $ALBUM

if [ "$?" = "1" ]; then
exit 100
fi

# Nombre base para las fotos (en el sub dir)

FILE="./"$ALBUM"/"$ALBUM"_foto_"

function pregunta(){
echo "-------------------------------------------------------------------------"
echo
echo "******************************"
echo "Nº fotos escaneadas: " "$I"
echo "******************************"
echo -e "Presionar:\n    * n para salir\n    * Otra tecla para escanear."
echo
read -s -n1 -p "Escanear una nueva foto ?" keypress
echo
}

###############################################

# Inicio

###############################################

I=0

pregunta

while [ "$keypress" != "n" ]; do
# nueva foto a escanear
let "I += 1"
NOMBRE=$FILE$I
scanimage $PARAMETROS| convert  -  $NOMBRE.jpg
pregunta
done


Sugerencias

Usar resoluciones altas como las del ejemplo hace que sea mucho mas lento el escaneado.

Hay que tener en cuenta que si se quiere imprimir una fotografía en papel se necesitan unos 250 puntos por pulgada. Si la idea de escanear las fotos es imprimirlas al mismo tamaño que el original, basta con una resolución de 250. Para verlas en un monitor con 100 alcanza y sobra. Una resolución más alta serviría para una ampliación.

Conviene preparar previamente la pila de fotos de manera que cada foto esté al derecho. De esta manera no perderás tiempo al ponerla en el escáner para que no queden rotadas 180º.

Al calibrar las medidas de los parámetros de la geometría conviene observar en qué posición hay que colocar el original, para que las imágenes digitales no queden "patas para arriba". En mi caso la parte de abajo de la foto va junto al eje 'l'.

Si tenés un sólo escáner conectado no dudes en no usar la opción -d. En el script es DEV=""

A veces cambian los numeritos en "xerox_mfp:libusb:001:003" y deberás modificarlo cada vez que uses el script.

Cuidado con los guiones y las comillas al copiar el script. Los guiones (el signo menos) pueden ser uno o dos juntos según la opción; las comillas son las dobles del teclado, no son las que ponen algunos procesadores de texto como LibreOffice.

Por seguridad, el script no crea el directorio si ya existe, para no sobrescribir archivos si los hubiese. En ese caso se detiene.

Si el álbum de fotos es viejo, no lamentarse si en las imágenes abunda el pelo, faltan arrugas ó faltan kilos :-

Bloggroll

Páginas vistas en total

Blog Archive