Modificar imágenes desde la línea de comandos con ImageMagick

ImageMagick es un completísimo paquete de programas multiplataforma para el tratamiento de imágenes. A diferencia de programas como Photoshop o Gimp, los programas que lo componen se ejecutan desde la línea de comandos, aunque también dispone de un sencillo entorno para X Window en Linux.

Entorno gráfico de ImageMagick en Linux

Tiene numerosas herramientas que, entre otras cosas, permiten:

  • Convertir entre una gran cantidad de formatos de imágenes.
  • Manipular la paleta de colores de una imagen.
  • Añadir tramados.
  • Crear un gif animado a partir de varias imágenes.
  • Superponer una imagen encima de otra.
  • Añadir texto a una imagen.

En la documentación se puede ver un listado detallado.

En la web es frecuente que el gestor de contenidos cree automáticamente réplicas de diferentes tamaños a partir de una imagen subida por el usuario para su correcta visualización en diferentes páginas. Por lo tanto, sin duda lo más usado para la web es su capacidad de reescalar imágenes, para lo que usa el algoritmo de «liquid rescaling«. Ademas la modificación de tamaño es muy flexible, permitiéndonos lograr la modificación que estemos buscando.

Tal vez algún lector se esté preguntando que habiendo programas con entorno gráfico como los citados más arriba, para qué trabajar en el modo texto de la shell de Linux/Unix. Veamos entonces un caso en que sería conveniente. Resulta fácil que una web acabe teniendo miles de imágenes distribuidas en cientos o miles de directorios, pues, por cada imagen que el administrador del contenido sube se van a crear varias copias con diferentes tamaños. Fácilmente el total de imágenes de un catálogo de productos, por ejemplo, se vuelve inmenso. Imaginemos que un cambio de diseño o la necesidad de hacer la web responsive hace necesario modificar el tamaño de una de las copias que se estaba guardando de cada imagen. En vez de modificarlas una a una con nuestro programa de edición de imágenes favorito, se puede crear un shell script como este:

ls *jpg | while read i
do
f=`basename $i .jpg`
convert $i -resize 200x200 smaller-$f.jpg
done

Lo que hace es buscar todas las imágenes jpg del directorio y gracias al comando convert de ImageMagick crea una copia más pequeña reescalada a 200×200 píxeles cuyo nombre será la cadena «smaller-» concatenada al nombre del fichero original. Fácilmente se podría modificar el script para que recorriera recursivamente todos los subdirectorios.

Todo lo que nos ofrece ImageMagick se puede utilizar desde diferentes lenguajes de programación y no solo porque desde éstos se pueda invocar comandos en la shell* y por lo tanto a ImageMagick, si no que el paquete ha sido portado. Está disponible en Java, .NET, Ruby, Pearl, Python, Php, etc. Aquí hay una lista detallada de todos.

En el caso concreto de PHP existe la extensión nativa IMagick. Sin duda es GD la extensión más extendida, valga la redundancia, en PHP. A pesar de su mayor propagación, y como es tan frecuente en el mundo de la informática, IMagick presenta algunas ventajas sobre GD que la convierten en una mejor extensión para trabajar con imágenes. Aquí un artículo con una comparación entre ambas.


* Como hace Drupal, el extendido CMS en PHP.


Aunque la palabra comando es un calco de inglés y en español es más correcto usar orden o instrucción, uso el término que usamos habitualmente en nuestro trabajo.


 

Lesbian in the shell

Desde que instalé Debian por primera vez, hará ya unos 14 años, tengo la costumbre de llamar «Lesbian» a cualquier ordenador de mi propiedad que lleve Linux. Por cierto, casi siempre he usado la distribución Debian o una variante.

Lesbian in the shell

Shell in the Lesbian

Ghost in the shell

Ghost in the shell. De moda otra vez después de más de 20 años. Ahora Motoko Kusanagi sufre un whitening.

Javascript ya no es un lenguaje de juguete

Hace años que Javascript ya no es un lenguaje de juguete con el que manipular con Dios y ayuda el DOM del navegador1 y para muestra un botón, ¡pero qué botón!

Emulador de PC con Javascript

También incorpora una versión reducida del compilador gcc

Se trata de un simulador de PC desarrollado en Javascript que puede ejecutarse perfectamente en tu navagador. Concretamente emula un procesador 486 (sin coprocesador matemático), RTC (reloj interno), puerto serie, disco duro, etc.

Además el emulador no viene solo sino que incorpora un Linux (Kernel 2.6.20) y una versión del compilador GCC que el mismo programador del emulador creó: Tiny C Compiler. Se trata de una versión mucho mucho más ligera y rápida que el compilador original.

El genial autor de esta obra es el francés Fabrice Bellard. Es un su web podéis encontrar otras muestras de su genio.

Desde que en 2008 los navegadores empezaron a incorporar compiladores JIT en vez de interpretar el código Javascript, la velocidad de ejecución dio un enorme salto. A medida que van mejorando (hoy en día son capaces incluso de optimizar código) siguen reduciéndose los tiempos. Esto ha dado más alcance a Javascript, por ejemplo Node.js funciona mediante una implementación en el lado servidor del compilador JIT para Chrome llamado V8.

Eso sí, a pesar de todas las librerías y software que ha crecido entorno a este lenguaje, y a pesar de su evolución, sigue teniendo características que hacen difícil la vida del programador:


1 Posiblemente las dificultades más que ser debidas a carencias de Javascript lo eran por los bugs de los navegadores a la hora de manipular el Document Object Model y a las diferencias entre ellos para implementar su manipulación (o el estándar no era muy concreto o era ignorado donde convenía implementarlo de otra manera, no lo sé). En todo caso, sobre Javascript recaían parte de las culpas con el consiguiente desprestigio.

Cómo instalar XCache en un servidor compartido

La semana pasada quise instalar en un servidor compartido (Hostmonster para más señas) alguno de los diferentes sistemas de caché que existen para PHP. El único que ofrecen es un paquete de PEAR llamado “Cache” pero necesitaba instalar Apc, Xcache, MemCache o Redis. Me puse en contacto con su departamento técnico para consultar si era posible y la respuesta fue un no. Como cuando instalamos Subversion tampoco fueron ni muy optimistas ni proactivos, no hice demasiado caso a su respuesta y me lancé a intentarlo. Como Apc parecía que iba a ser problemático pues por lo que leí necesitaba ser root, lo intenté con Xcache. En primer lugar, en el directorio “home” de mi usuario en Hostmonster creé los directorios y bajé la versión de xCache para la versión de PHP que corre el servidor:

  1. mkdir modules xcache
  2. wget http://xcache.lighttpd.net/pub/Releases/1.3.2/xcache-1.3.2.tar.gz

Después descomprimí el módulo y lo compilé para la versión de PHP del servidor:

  1. tar -zxf xcache-1.3.2.tar.gz
  2. cd xcache-1.3.2
  3. phpize
  4. ./configure –enable-xcache
  5. make

Compruebo que esté bien:

  1. make test

Y ya sólo queda mover el módulo recién compilado a su directorio de destino:

  1. cd modules
  2. mv xcache.so /home2/usuario/modules

Ahora debemos editar php.ini para que PHP empiece a trabajar con Xcache. Añadí las siguientes líneas:

  1. zend_extension = /home2/usuario/modules/xcache.so
  2. zend_extension_ts = /home2/usuario/modules/xcache.so
  3. xcache.shm_scheme = «mmap»
  4. xcache.size = 32M
  5. xcache.count = 8
  6. xcache.slots = 8K
  7. xcache.ttl = 0
  8. xcache.gc_interval = 0
  9. xcache.var_size = 16M
  10. xcache.var_count = 1
  11. xcache.var_slots = 8K
  12. xcache.var_ttl = 0
  13. xcache.var_maxttl = 0
  14. xcache.var_gc_interval = 300
  15. xcache.test = Off
  16. xcache.readonly_protection = Off
  17. xcache.mmap_path = «/dev/zero»
  18. xcache.coredump_directory = «»
  19. xcache.cacher = On
  20. xcache.stat = On
  21. xcache.optimizer = Off
  22. xcache.coverager = Off
  23. xcache.coveragedump_directory = «»

También le podemos añadir un usuario y contraseña, ésta última debe ir “hashed” con md5 según explica la documentación:

  1. xcache.admin.user = «nombre_del_usuario»
  2. xcache.admin.pass = «4c882dcb24bcb1bc225391a602feca7c»

Para que la configuración tenga efecto deberíamos reiniciar los procesos fcgiphp5 pero eso no es siempre posible en un servidor compartido, así que no me quedó otra que esperar a que ello sucediera. Se pueden ver los procesos de la siguiente forma:

  1. ps aux | grep fcgiphp5

A continuación obtenemos la id del proceso y mediante kill mandamos la señal para matarlo. En todo caso, sea de este modo o bien esperando, en el resultado de phpinfo() deberíamos ver esto si XCache está funcionando correctamente:
XCache correctamente instalado

Configuración XCache

Configuración XCache

Instalarlo es muy fácil, ¿verdad? A continuación me puse otra vez en contacto con ellos para preguntarles si tenían algún inconveniente con la instalación pues mejor prevenir a que deshabiliten la web y su respuesta fue que no veían ningún inconveniente. Como pueden observar, en este tipo de servicios de alojamiento web es mejor ser proactivo y lanzarse a ver si es técnicamente posible.