[herramientas] Tratando imágenes con ImageMagick

Hola mi gente beeeeeiaa... (?)

En esta ocasión quiero mostrarles cómo usar uno de los programas que por lo general suele pasar inadvertido para el usuario de GNU/Linux, pero que esconde un gran poder en su interior... Estoy hablando de ImageMagick (ver acá), que es nada más y nada menos que una colección de utilidades para el tratamiento de imágenes.

Mediante este programa podremos editar nuestras imágenes a través de la línea de comandos. Si bien para estos menesteres solemos hacer uso de Gimp, que por si fuera poco posee una interfaz gráfica divina para agrado y deleite de los bobitos de la nueva ola (?), lo cierto es que ImageMagick patea traseros... Bueno, no tan de ese modo. Ambas herramientas pueden convivir y complementarse. Por un lado Gimp (o el programa de edición que prefieran con interfaz gráfica) es ideal para retoques finos, por el otro, ImageMagick se luce a la hora de lidiar con enormes cantidades de imágenes a la vez y es que de hecho es ahí donde se aprecia mejor su potencia... ImageMagick nos permite trabajar optimizando tiempos de manera rápida y eficiente con una enorme cantidad de archivos de distinto formato a la vez a través de la ejecución de simples comandos y nos evita el tedio y el fastidio de tener que abrir un programa pesado para ello.


CONSIDERACIONES PREVIAS

Primero. Para ejecutar las órdenes que se detallarán más adelante debemos tener en cuenta que lo vamos a hacer por medio de un emulador de terminal (yo uso Tilda, a veces Guake, pero también existen: Gnome Terminal, Xterm, etc.). Luego, debemos saber cómo movernos entre los directorios (carpetas) de nuestro sistema haciendo uso de éste ya que para ejecutar las órdenes (por razones de comodidad) debemos estar en el directorio donde se encuentran las "imágenes de entrada" (o sea las imágenes que vamos a manipular con ImageMagick).

Segundo. Si advierten palabras encerradas entre llaves en las órdenes genéricas que verán más abajo no es más que para advertirles que podrán sustituirlas a criterio de ustedes. Igualmente siempre les voy a decir por qué "cosas" sí podrán hacerlo. Mientras tanto les voy a explicar cómo tienen que sustituir {entrada} (las imágenes que vamos a modificar) y {salida} (las imágenes resultantes ya modificadas) que requieren una explicación especial.

Supongamos que en una carpeta (directorio) tenemos las siguientes imágenes:

a-imagen1.jpg
b-imagen2.jpg
b-imagen3.png
a-imagen4.svg
b-imagen5.tiff
c-imagen6.jpg
a-imagen7.png

Si sólo queremos modificar las de extensión .jpg reemplazamos *.jpg por {entrada}, si queremos modificar las de extensión .jpg y también las de extensión .png reemplazamos *.jpg *.png por {entrada}, si no nos importa la extensión de las imágenes y queremos modificarlas a todas entonces reemplazamos * por {entrada}. También podemos seleccionar de a una. Si queremos modificar sólo la imagen c-imagen5.jpg reemplazamos c-imagen5.jpg por {entrada}, si queremos modificar sólo la primera y la segunda imagen de la lista entonces reemplazamos a-imagen1.jpg b-imagen2.jpg por {entrada} y así... Por último, notamos que existe un patrón en los nombres de las imágenes, una partícula que se repite, entonces si queremos modificar las que empiezan por b (sin importarme el formato) reemplazo b* por {entrada}.
Esto de seleccionar, o mejor dicho filtrar, imágenes debemos tenerlo muy claro ya que nos ahorrará muchísimo tiempo y permitirá trabajar con enormes cantidades de imágenes a la vez.
Por último un consejo que pueden seguir o no (problema de ustedes). Cuando deban nombrar un archivo de imagen no dejen espacios en blanco, prefieran los "guiones bajos" en su lugar o HaganloDeEstaForma y eviten acentuar. A su vez, si tienen varias imágenes de distinto tema y deben volcarlas a todas en una misma carpeta, sepárenlas por medio de partículas de este modo: FiestitaDelaYani-imagen1.jpg FiestitaDelaYani-imagen2.jpg PartuzaDelNico-imagen1.jpg y así... De este modo será luego más práctico para ustedes manipularlas y agilizarán procesos...

Por otra parte {salida} puede ser "cualquier cosa" que respete esta forma: nombre.extensión como por ejemplo salida.png o sea, dicho de otro modo, es un nombre que designaremos nosotros a gusto y piacere con la extensión que queramos.
Por lo general la única regla es que {salida} no sea reemplazado por el nombre de un archivo que colocaron en {entrada} o el programa sobreescribirá en esa imagen los cambios que hagamos.
Tengan en cuenta también que si el programa necesita generar más de un archivo de salida lo hará automáticamente de este modo: nombre-0.extensión nombre-1.extensión nombre-2.extensión y así sucesivamente. Así que no se preocupen por eso.
Un consejo, si sólo reemplazan {salida} por "cualquier cosa" que respete nombre.extensión los archivos de salida se generarán en el mismo directorio donde se encuentran las imágenes de entrada. Si queremos evitar eso, en vez de {salida} pondremos "algo" que respete: ruta/nombre.extensión donde "ruta" ha de ser la dirección a otro directorio que queramos (debe existir). De esta manera nos ahorraremos el paso de tener que mover los archivos luego...

Por último, nada, sólo decirles que para los ejemplos usé de entrada esta imagen de 370x250 píxeles:

[herramientas] Tratando imágenes con ImageMagick

Bueno esto fue todo el sermón inicial, pasemos a la acción...


TRATANDO IMÁGENES CON IMAGEMAGICK



  • CONVERTIR A OTROS FORMATOS

ImageMagick soporta la conversión entre una enorme variedad de formatos de imagen (ver acá).
Para cambiar el formato de una imagen basta con ejecutar:

convert {entrada} {salida}

  • REDIMENSIONAR

El cambio de tamaño de una imagen se consigue mediante la orden:

convert -resize {dimensión} {entrada} {salida}
Donde {dimension} es el tamaño en píxeles al que se quiere redimensionar la imagen de entrada. Por ejemplo, si en lugar de {dimensión} ponemos el número 200 lo que vamos a conseguir es redimensionar la imagen de entrada a 200px de ancho (la altura va a ser calculada automáticamente por el programa manteniendo la relación de aspecto). El resultado se aprecia a continuación:

Software Libre

Si lo que nos interesa es redimensionar la altura de la imagen a 200px, sin importarnos el ancho, entonces en lugar de {dimensión} introducimos la letra x seguida inmediatamente por el número 200 así: x200, luego ejecutamos la orden y como resultado vamos a obtener lo siguiente:

tutorial

Noten dos cosas: una, que no necesariamente se obtiene lo mismo redimensionando de ancho que de alto pese a que introducimos el mismo número y, dos, que en los casos anteriores el programa siempre conserva la relación de aspecto. Ahora suponiendo que eso de la relación de aspecto nos importa un joraca y se nos canta redimensionar nuestra imagen de entrada a 150px de ancho por 300px de alto. Bueno, en ese caso, en vez de {dimension} introducimos \!150x300 y conseguimos esto:

edicion de imagenes

La verdad es que la imagen de salida no se ve bien ya que existe una distorsión muy notoria (adrede, puesto que lo hice así para que ustedes lo noten) propia de la pérdida de la relación de aspecto, pero en fin, cada uno hace lo que se le canta el toor... Ustedes sepan que existe esta alternativa también por si la llegan a necesitar.

Sepan además que otra forma de agrandar y achicar imágenes es mediante la orden:

convert -resize {porcentaje} {entrada} {salida}
Ésta es igual a la anterior, sólo que debemos introducir porcentajes en vez de dimensiones en píxeles. De esta manera el tamaño de nuestra imagen de entrada representa el 100% y si nosotros queremos, por ejemplo, agrandarla un 10% de ancho debemos introducir 110% en lugar de {porcentaje} ya que si introducimos 10% lo que conseguimos es achicarla hasta ese porcentaje.
En conclusión, excepto que se usan porcentajes en vez de dimensiones en píxeles, esta orden admite el mismo tratamiento que la anterior.


  • VOLTEAR

Horizontalmente:

convert -flop {entrada} {salida}
gnulinux

Verticalmente:

convert -flip {entrada} {salida}
ImageMagick

Incluso se puede combinar ambas órdenes para ahorrarnos un paso:

convert -flip -flop {entrada} {salida}
gnu y linux


  • ROTAR

Conocida también como "girar". Lo que hace la orden siguiente es exactamente eso: gira la imagen en sentido horario en un ángulo que nosotros debemos indicar.

convert -rotate {angulo} -background {color} {entrada} {salida}
Antes que nada sepan que {color} (que en este caso hace referencia al que queremos para el fondo) puede ser sustituido por el nombre de un color en inglés (en el ejemplo usé un simple white), por un equivalente hexadecimal del modo "#ffffff" (con las comillas), entre otras formas de notación para colores que no viene al caso tratar. Otra cosa muy interesante es que si cuando debemos especificar un color introducimos transparent lo que vamos a conseguir es transparencia para esa zona a la que asignamos ese "color", no obstante para que esto se vea reflejado en la imagen de salida ésta debe tener un formato que soporte transparencias (como las imágenes de extensión .png). Por último, desde ahora en adelante, siempre que deban declarar un color en ImageMagick tengan en cuenta este párrafo. No voy a volver a profundizar sobre esto...
Luego, al parecer no hay mucho que explicar, para el ejemplo reemplacé {angulo} por 25 (o sea 25 grados) y obtuve esta imagen:

Trisquel GNULinux

Ah sí, me olvidaba, si en vez de {angulo} se introduce un número negativo, la imagen rotará en sentido antihorario.

[herramientas] Tratando imágenes con ImageMagick


  • AGREGAR BORDES

Esto lo vamos a conseguir mediante la ejecución de esta orden:

convert -bordercolor {color} -border {horizontal}x{vertical} {entrada} {salida}
Por un lado {color} hace referencia en este caso al color del borde, declárenlo de acuerdo a la explicación de más arriba (para el ejemplo de abajo usé gray), por otro lado, {horizontal} es un número en píxeles que hace referencia al ancho de los bordes laterales de la imagen y {vertical} hace lo propio con los bordes superior e inferior. En el ejemplo de abajo reemplacé {horizontal}x{vertical} por 10x20 para que se note esto que se está indicando.

Software Libre

De todas formas ésta no es la única forma de obtener bordes para nuestras imágenes, existen otras mediante efectos. Por ejemplo, ejecuto:

convert -raise {horizontal}x{vertical} {entrada} {salida}
Y éste es un resultado posible:

tutorial

O si ejecuto:

convert -polaroid {angulo} -background transparent {entrada} {salida}
Puedo obtener un "efecto Polaroid" o efecto imitación de fotografía:

edicion de imagenes

Nota: no sé si es un bug o qué, pero no consigo que el fondo sea de "un color" distinto de transparente, por ello es que la orden para este efecto es la dada (tengan en cuenta que si usan fondo transparente el formato de la imagen debe soportarlo).

Incluso existen bordes biselados, suelen servir, o servían, para hacer botones o imitación de cuadros, pero creo que ya es suficiente con lo expuesto hasta ahora sobre este tema.


  • APLICAR EFECTOS

ImageMagick deja a nuestra disposición una gran variedad de efectos para que retoquemos nuestras imágenes. Anteriormente mostré un "efecto Polaroid", ahora, en este caso quiero mostrarles cómo aplicar un efecto sepia (de los que más me gustan a mí en lo personal) así que ejecuto:

convert -sepia-tone {porcentaje} {entrada} {salida}
Donde sólo se debe variar el porcentaje para conseguir que el efecto sea más agradable a nuestro gusto. Por ejemplo si en vez de {porcentaje} pongo 75% consigo este resultado:

gnulinux

Les dejo a ustedes la tarea de investigar sobre el resto de los efectos disponibles...


  • VARIAR NIVELES DE BRILLO, SATURACIÓN Y TONO

De entrada los niveles de brillo, saturación y tono de una imagen se encuentran al 100%, entonces si nosotros queremos aumentar alguno de ellos debemos usar un número superior al 100, mientras que si lo que queremos es bajarlos debemos introducir números menores. Esta es la orden genérica:

convert -modulate {brillo},{saturacion},{tono} {entrada} {salida}
Por ejemplo, si en vez de {brillo},{saturacion},{tono} introduzco 120,0,100 hago que mi imagen cambie a blanco y negro (ya que bajé la saturación a cero) y que tenga algo más de brillo, así:

ImageMagick

Por otro lado, si coloco 100,100,120, obtengo esta otra imagen:

gnu y linux

En este caso sólo varié un poco el tono.

En fin, existen infinitas combinaciones posibles para experimentar.


  • JUNTAR O UNIR

Supongamos que queremos unir varias imágenes una después de la otra y/o una abajo de la otra. Va de nuevo, supongamos que queremos unir seis imágenes en dos filas y tres columnas. Bueno esto se consigue así:

montage -tile {columnas}x{filas} -geometry +{horizontal}+{vertical} -background {color} {entrada} {salida}
Donde {columnas}x{filas} en nuestro caso es reemplazado por 3x2 y donde +{horizontal}+{vertical}, que hace referencia al ancho en píxeles de los "separadores" de las imágenes, es sustituido por +2+2 (si no se quiere usar "separadores" en vez de +2+2 se debe declarar +0+0). Éste es el resultado (observación: luego de obtener la imagen la redimensioné para adaptarla al sitio):

Trisquel GNULinux

Una idea: observen las imágenes que coloqué a la izquierda en la imagen compuesta, la de arriba y la de abajo, parecen espejadas. Puede llegar a ser un efecto interesante...


  • INSERTAR TEXTO

Bueno, esto lo conseguimos mediante la orden:

convert -font {fuente} -pointsize {tamaño} -gravity {posicion} -fill {color} -draw 'text {horizontal} {vertical} "{texto}"' {entrada} {salida}
Pasemos a la explicación... {fuente} es, valga la redundancia, el nombre de la fuente que queremos usar (debemos tenerla instalada en nuestro sistema; incluso, y más recomendable, podemos especificar la ruta completa hacia ella). Su tamaño en píxeles y color están dados respectivamente por {tamaño} y {color}. {posicion}, por otra parte, hace referencia a la ubicación del texto que vamos a insertar en la imagen (puede ser: north, northeast, northwest, south, southeast, southwest, center, east, west, en fin). Luego {horizontal} y {vertical} son los márgenes, en píxeles, que habrá entre el texto y los lados de la imagen (si declaramos 0 0 el texto estará pegado contra ellos).
La inserción de texto en imágenes se puede usar para identificarlas, como una simple marca, para poner la fecha y lugar donde fue tomada, etc. Un resultado posible es el que se ve a continuación:

[herramientas] Tratando imágenes con ImageMagick

Sepan que se puede añadir más de una cadena de texto a la misma imagen, para ello sólo tenemos que agregar otra vez -font {fuente} -pointsize {tamaño} -gravity {posicion} -fill {color} -draw 'text {horizontal} {vertical} "{texto}"', pero con las preferencias para la nueva cadena, a continuación de convert. Tengan en cuenta que si insertan más de un texto puede que tengan que acomodarlos modificando lo que ponen en {horizontal} y en {vertical} o puede que aparezcan encimados. Ésta es una imagen de ejemplo para que vean las posibilidades que tienen a mano:

Software Libre

Incluso se puede generar imágenes desde cero (esto es sin tener que especificar una de entrada) con texto insertado ejecutando:

convert -size {ancho}x{alto} xc:{fondo} -font {fuente} -pointsize {tamaño} -gravity {posicion} -fill {color} -draw 'text {horizontal} {vertical} "{texto}"' {salida}
De esta orden la mayoría de sus partes ya las conocemos. Noten que no hay que declarar una imagen de entrada ya que su función no es modificar una imagen existente, sino generar una nueva. Las dimensiones de ésta van a estar dadas por lo que pongamos en {ancho}x{alto} y en {fondo} podemos especificar que el fondo sea transparente o bien del color que queramos como lo venimos haciendo hasta ahora.
A partir de esta orden, la imagen original y lo aprendido sobre unión de imágenes conseguí el resultado que se ve abajo:

tutorial

Dominar la técnica de inserción de texto en ImageMagick puede ser un tanto complicado, pero con práctica se consiguen muy buenos resultados...


  • CAMBIAR EL ESPACIO DE COLOR

Los colores se forman de distinta manera dependiendo del modelo o espacio de color (ver acá). Para definir el espacio de color de nuestra imagen podemos valernos de la orden siguiente:

convert -colorspace {espacio} {entrada} {salida}
Si queremos consultar los espacios de color disponibles, antes podemos ejecutar:

convert -list colorspace
Esto nos devolverá una lista con todos los que tengamos a disposición y que podemos sustituir por {espacio} en la orden de más arriba.
Esto suele ser útil a la hora de imprimir nuestras imágenes.


  • COMBINAR

Cuando expliqué cómo unir imágenes lo que en realidad hice es mostrar un tipo de combinación de éstas. Pero supongamos que queremos "pegar" una imagen encima de la otra y no una junto a la otra. Bueno, en esos casos es donde haremos uso de esta orden en concreto:

composite -gravity {posicion} -geometry +{horizontal}+{vertical} -dissolve {porcentaje} {entrada} {salida}
Nota: si a +{horizontal}+{vertical} lo reemplazamos por +0+0, la imagen superior va a estar "pegada" contra los lados dependiendo de lo que hayan indicado en {posicion}. De esto se deduce que manipulando los valores que demos a {vertical} y a {horizontal} vamos a conseguir un ajuste mucho más fino de la posición de la imagen superior.

De esta manera podemos lograr resultados como el que se muestra a continuación:

edicion de imagenes

Ahora supongamos que quiero poner la siguiente marca de agua (generada también con ImageMagick) a mi imagen original:

gnulinux

Bueno, en este caso puedo variar el porcentaje de disolución hasta uno que me satisfaga y con ello conseguir algo parecido a esto:

ImageMagick

Para el ejemplo usé un 40%, pero es a gusto de cada uno, un 100% indica que no queremos usar disolución. Es decir, a medida que el porcentaje de disolución disminuya la imagen que superpongamos o "peguemos" se irá volviendo cada vez más transparente.

La combinación de imágenes es muy útil para hacer montajes, en un futuro voy a mostrarles cómo hacerlos usando ImageMagick y sin disponer de la opción "varita mágica" muy común en los programas de diseño con interfaz gráfica.


  • ANIMAR

Si queremos crear una imagen .gif a partir de imágenes estáticas que tengamos tiradas por ahí podemos hacerlo de este modo:

convert -delay {tiempo} -loop {cantidad} {entrada} {salida}
Donde {tiempo} es un número en milisegundos que indica cuánto tardará la transición de un fotograma a otro y {cantidad} es el número de veces que se repetirá la secuencia (si ponemos 0 se repetirá indefinidamente como suele ser habitual en este tipo de imágenes).

Nota: en este caso la imagen de salida debe tener sí o sí la extensión .gif o sino no vamos a lograr el resultado esperado.

Por otra parte, si necesitamos extraer los fotogramas de una imagen .gif podemos hacer uso de esta otra orden:

convert -adjoin {entrada} {salida}
Donde ahora el archivo de entrada debe ser una imagen con extensión .gif o de nuevo no conseguiremos nuestro cometido. Los archivos de salida pueden tener cualquier formato de imagen estática como .jpg o .png por ejemplo.


  • CAPTURAR PANTALLA

Esta funcionalidad es ideal, sobre todo, para sistemas minimalistas donde disponemos de simples manejadores de ventanas en vez de complejos entornos de escritorio. De esta manera, si nos damos algo de maña podemos mapear ciertas combinaciones del teclado con las órdenes que voy a dar a continuación para poder ejecutarlas con sólo presionar un par de teclas.

En fin...

Para capturar la pantalla completa:

import -window root {salida}
Nota: si estamos en un entorno sin X también se puede hacer uso de esta orden.

Para capturar una ventana:

import {salida}
En este último caso el puntero del mouse se transformará en una cruz que si la posamos sobre una ventana y hacemos clic sobre ella conseguiremos capturarla. Incluso si mantenemos presionado el botón de acción y arrastramos el mouse podremos capturar una sección de esa ventana.


CONSIDERACIONES FINALES

Una última aclaración para ir cerrando la persiana... Con convert lo que hacemos no es en sí modificar una imagen, sino generar una nueva a partir de la que especifiquemos en la entrada. Si lo que queremos es sí o sí modificar una imagen, o sea, que el programa sobreescriba los cambios en la imagen que especifiquemos de entrada debemos sustituir derecho viejo (lo único que va a cambiar es que ya no deben hacer uso de {salida} al ejecutar una orden, así que ignoren esa parte) convert por mogrify. Este último hace lo mismo que convert cuando declaramos el mismo nombre con la misma extensión para el archivo de entrada y el de salida, pero la diferencia radica en que mogrify puede modificar grandes cantidades de imágenes. "Úsenlon" con moderación o pueden estropear sus imágenes... Comiencen de a un archivo de entrada hasta que le agarren la mano y luego vayan incrementando las cantidades.

Por último, sólo decir que lo que mostré en esta ocasión no es todo el arsenal de cosas que se pueden hacer con ImageMagick, de hecho es sólo una pequeña parte, lo básico como para que ustedes arranquen y puedan empezar a utilizarlo. Para funciones más avanzadas deberán investigar ustedes mismos, sin embargo en el futuro seguramente les mostraré otras cosas que se pueden hacer con este noble programa.

El único límite está dado por la capacidad de imaginación de cada uno.

Bueno... Esto fue "[herramientas] Tratando imágenes con ImageMagick"... Espero que les haya gustado... ¡Chau!


3 comentarios - [herramientas] Tratando imágenes con ImageMagick

@elbuglione +3
bastante bueno para un usuario no profesional, pero para trabajos profesionales, sigo optando por GIMP.
@k-kman +2
@LegnaZen Mi cuñado es diseñador web, diseñador de videojuegos y además diseña tatuajes y para todo usa Gimp. Sique si,los profesionales tambien lo usan, pero solo que la mayoria aprende primero Adobe y despues le cuesta despegarse.
Y eso de trabajar en lotes está de 10
Saludos che!
@LegnaZen
@k-kman saludos... y qué groso tu cuñado
@fabito1945
Por mas profesional que seas si tenes que redimensionar mas de 30 imágenes y tenés poco tiempo no te queda otra que usar esto. Te hacés un script con un for y listo.
@foxsermon +1
+10 y a favoritos !!

Use esta herramienta para recuperar varias fotos de un SD que quedo mal con una camara digital chafa... pude recuperar muchas fotografias pero se perdieron algunas importantes
@LegnaZen +1
@foxsermon qué bueno que hayas podido recuperar muchas de esas fotos, lo lamento por las otras... por eso no confío en esas memorias, siempre hago backup de los archivos importantes en cd... ahora, que yo sepa ImageMagick no posee la función para recuperar archivos, al menos no directamente... tal vez hayas usado Foremost o Scalpel para recuperarlos...
@LegnaZen
...y luego usaste el poder de ImageMagick para filtrar las imágenes como él: http://javier-tobal.blogspot.com.ar/2014/01/usos-de-imagemagick-filtrar-falsos.html

gracias por comentar!!!
@JaVi_ITZ +1
Muy buen post y muy buena herramienta. Tomé contacto con ella para extraer los frames (cuadros) de un GIF y poderlos unir con ffmpeg para convertirlos en un video, codec de por medio, y asi poderlos pasar por Whatsapp .

convert -coalesce {entrada} jpg:{salida} + "%04d.jpg"
@LegnaZen
bien ahí... tenía pensado explicar lo opuesto: cómo crear un gif a partir de un video tomando solo la parte que nos importa de éste... otra: cómo poner una marca de agua en un video... en ambos casos uniendo fuerzas con ffmpeg o libav, claro...
pero va a tener que ser luego porque estoy luchando con hacer andar el **** mediagoblin... se me hizo obsesión
gnu y linux
@LegnaZen
@JaVi_ITZ gracias por comentar, la buena onda y compartir tu experiencia!!