Introducción
Hace cerca de un año llego a mi un proyecto el cual consistía en generar un sistema de perfiles de personas.
La idea era bastante sencilla, los usuarios tendrían la posibilidad de crear su perfil el cual se guardaría en una base de datos, sin embargo mi cliente quería que los usuarios tuvieran la capacidad de hacer su propia galería de imágenes.
Esta última cosa complicaba un poco las cosas, pues no podemos esperar que un usuario normal conozca mucho de imágenes, normalmente guardan sus fotos en un despliegue gigante y con un tamaño de disco que llega a los megas. Esto significaba un costo tanto en ancho de banda como en la propia interfase, pues los tamaños de las imágenes serían tan variados que no podrías hacer una interfase general, y se descartaba de inmediato el obligar que los usuarios editarán sus imágenes a un tamaño específico y que aparte las comprimieran.
Inmediatamente me puse a pensar, bueno pensar es una exageración, lo que hice fue entrar a la web y buscar a ver si alguien había llegado a alguna solución.
Lo primero que me encontré fue el Image::Magick, realmente era impresionante la cantidad de cosas que puedes hacer con él. Este módulo te da una gran variedad de herramientas para editar imágenes por medio de perl.
Descargué el tutorial, lo imprimí y me puse a estudiarlo. Finalmente hice el script que me funcionaba de maravilla, entonces decidí probarlo ya en vivo. Pero encontré mi gran problema, me fue imposible instalar el módulo, y ni siquiera pude usarlo como una librería externa, entonces estaba totalmente fuera de discusión el usar este gran módulo, de regreso al paso uno.
Frustrado seguí buscando, y encontré lo que fue mi salvación, un par de módulos:
GD
Image::GD::Thumbnail
Creando los thumbnails
Realmente se van a impresionar con lo fácil que es hacer thumbnails usando este par de módulos.
Lógicamente lo primero que debemos de hacer es cargar nuestros módulos:
#!/usr/bin/perl -w
use strict; #No nos olvidemos de este pragma
use GD;
use Image::GD::Thumbnail;
Después vamos a usar el módulo GD para leer nuestra imagen:
# Cargamos la imagen
open IN, "imagen.jpg" or die "No se pudo abrir imagen: $!";
my $imagenPrinc = GD::Image->newFromJpeg(*IN);
close IN;
Lo que hacemos es abrir la imagen de la cual queremos hacer el thumbnail (en este caso se llama "imagen.jpg"), y creamos un FILEHANDLE con el nombre de IN el cual luego enviamos al módulo GD por medio de la función newFromJpeg que si lee exitosamente la imagen regresa una imagen inicializada, de lo contrario regresaría undef, que normalmente sucede cuando es una imagen con formato desconocido.
NOTA: GD automáticamente hace la llamada a binmode(FILEHANDLE) en los sistemas operativos donde sea necesario, por ejemplo windows.
En el caso de este ejemplo estamos suponiendo que la imagen a cargar es de formato JPEG. En el caso de que quieran leer otro tipo de formatos, existen otras funciones, entonces sustituimos donde dice newFromJpeg por cualquiera de las siguientes:
- newFromPng para PNG
- newFromJpeg para JPG o JPEG
- newFromGif para GIF
Ahora vamos a pasar al siguiente paso, crear nuestro thumbnail. Para hacer el thumbnail todo lo que debemos de hacer es llamar la siguiente línea:
my ($thumb,$x,$y) = Image::GD::Thumbnail::create([IMAGEN GD],[TAMAÑO MÁXIMO]);
Lo que estamos llamando es la función create dentro del módulo Image::GD::Thumbnail. Ésta función recibe dos argumentos. El primer argumento es un objeto de imagen tipo GD, el cual se crea como vimos anteriormente. Y el segundo argumento es un número con el tamaño máximo que deseas que tenga la imagen.
La función redimensiona la imagen de una manera sencilla, si por ejemplo tenemos una imagen de 300x200 y queremos que el tamaño máximo sea de 150, va a buscar cual de x o y es mayor y redimensionar basándose en ello. En este caso la imagen redimensionada quedaría en 150x100. Pero si la imagen tuviera un tamaño de 120x440 al redimensionar tendríamos una imagen de 41x150.
NOTA: En el caso que ambos lados sean menores al tamaño máximo, de igual manera se redimensionan las imágenes, llenando el espacio con un fondo blanco.
Después de crear la imagen recibimos tres argumentos, el primero es el un nuevo objeto con la imagen ya redimensionada, el segundo es el tamaño final de x y el tercero es el tamaño final en y.
Siguiendo con nuestro ejemplo, las imágenes las vamos a redimensionar con un tamaño máximo de 150:
#Redimensionamos la imagen
my ($thumb,$x,$y) = Image::GD::Thumbnail::create($imagenPrinc,150);
Si todo sale bien, en la variable $thumb tendremos un objeto con nuestra imagen redimensionada, ahora falta crear el archivo con la imagen.
# Salvamos el thumbnail
open OUT, ">imagen_thumb.jpg" or die "No se pudo salvar: $!";
binmode OUT;
print OUT $thumb->jpeg;
close OUT;
Lo primero que hacemos es abrir un FILEHANDLE de escritura para un archivo. Luego llamamos el binmode (ahora si debemos de llamarlo manualmente), después llamamos la función jpeg del objeto $thumb escribiendo el resultado en el archivo, y finalmente cerramos el archivo.
Estamos llamando la función $thumb->jpeg pues en este ejemplo queremos crear JPGs, pero si estamos manejando otro tipo de imágenes, podemos llamar cualquiera de las siguientes funciones:
- $thumb->jpeg([CALIDAD]);
Para crear imágenes JPG o JPEG, y si queremos podemos decidir el tipo de compresión con un número entre 0 y 100, entre mayor sea el número menor la compresión y más grandes los archivos. En el caso de que no se especifique, GD seleccionará una buena compresión.
- $thumb->gif();
Para crear imágenes de tipo GIF.
- $thumb->png([CALIDAD]);
Para crear imágenes de tipo PNG, y si queremos podemos decidir el tipo de compresión con un número entre 0 y 9, donde 0 es sin compresión y 9 máxima compresión. En el caso de que no se especifique, GD seleccionará una buena compresión.
Notas Finales
Realmente es sencillo crear thumbnails con estos módulos. Les recomiendo que hagan pruebas para que encuentren la solución a su problema.
También les recomiendo que lean estos tutoriales relacionados con este tema.
Upload de archivos
Guardar imagenes en una base de datos
Leer dimensiones de las imágenes
Código Final
#!/usr/bin/perl -w
use strict; #No nos olvidemos de este pragma
use GD;
use Image::GD::Thumbnail;
# Cargamos la imagen
open IN, "imagen.jpg" or die "No se pudo abrir imagen: $!";
my $imagenPrinc = GD::Image->newFromJpeg(*IN);
close IN;
#Checamos si se pudo leer correctamente la imagen
if(defined($imagenPrinc)){
#Redimensionamos la imagen
my ($thumb,$x,$y) = Image::GD::Thumbnail::create($imagenPrinc,150);
# Salvamos el thumbnail
open OUT, ">imagen_thumb.jpg" or die "No se pudo salvar: $!";
binmode OUT;
print OUT $thumb->jpeg;
close OUT;
}
#No se pudo leer correctamente la imagen
else{
print "El formato de la imagen debe de ser JPG o JPEG\n";
}
exit(1);