Crear thumbnails (miniaturas) con php al vuelo.

Para reducir el ancho de banda en nuestro servidor, a costa de cargar la cpu un poco más, podemos redimensionar las imágenes que estamos sirviendo con un sencillo script de PHP. Vamos a ver dos métodos, uno con la librería gd y otro llamando a imagemagick.

Librería GD:

Usaremos un archivo php para hacer la carga de las imágenes, lo llamaremos thumb.php y lo colocaremos en la raíz de nuestra web. Lo llamaremos de la siguiente forma:

        <img src="/thumb.php?file=/public/image1.png&width=100" alt="miniatura" />

Le pasamos 2 parámetros al script:

file: la ruta a la imagen que queremos redimensionar.

width: la nueva anchura.

Lo primero que tenemos que hacer el calcular las nuevas dimensiones de la imagen, en nuestro ejemplo estamos marcando la anchura, y la altura se calcula a partir de ésta. Cuando ya tenemos las nuevas dimensiones vemos en qué formato está y luego escribimos las cabeceras correspondientes y la mostramos. El código del archivo thumb.php sería el siguiente:

        $file = $_GET["file"];
        $width = $_GET["width"];

        // Ponemos el . antes del nombre del archivo porque estamos considerando que la ruta está a partir del archivo thumb.php
        $file_info = getimagesize("." . $file);
        // Obtenemos la relación de aspecto
        $ratio = $file_info[0] / $file_info[1];

        // Calculamos las nuevas dimensiones
        $newwidth = $width;
        $newheight = round($newwidth / $ratio);
        
        // Sacamos la extensión del archivo
        $ext = explode(".", $file);
        $ext = strtolower($ext[count($ext) - 1]);
        if ($ext == "jpeg") $ext = "jpg";

        // Dependiendo de la extensión llamamos a distintas funciones
        switch ($ext) {
                case "jpg":
                        $img = imagecreatefromjpeg("." . $file);
                break;
                case "png":
                        $img = imagecreatefrompng("." . $file);
                break;
                case "gif":
                        $img = imagecreatefromgif("." . $file);
                break;
        }
        // Creamos la miniatura
        $thumb = imagecreatetruecolor($newwidth, $newheight);
        // La redimensionamos
        imagecopyresampled($thumb, $img, 0, 0, 0, 0, $newwidth, $newheight, $file_info[0], $file_info[1]);
        // La mostramos como jpg
        header("Content-type: image/jpeg");
        imagejpeg($thumb, null, 80);

Imagemagick

Si usamos imagemagick tenemos las ventajas de ahorrar consumo de memoria y los inconvenientes de que tenemos que tenerlo instalado en nuestro servidor. En caso de tenerlo disponible, el script resultante sería muy parecido al anterior

        $file = $_GET["file"];
        $width = $_GET["width"];

        // Ponemos el . antes del nombre del archivo porque estamos considerando que la ruta está a partir del archivo thumb.php
        $file_info = getimagesize("." . $file);
        // Obtenemos la relación de aspecto
        $ratio = $file_info[0] / $file_info[1];

        // Calculamos las nuevas dimensiones
        $newwidth = $width;
        $newheight = round($newwidth / $ratio);

        // No necesitamos sacar la extensión ya que el comando convert ya detecta el formato
        header("Content-type: image/jpeg");
        passthru("convert -scale ".($newwidth)."x".($newheight)."! "./".$file."" JPG:-");


Comentarios

Comentario de Chano - 12 de Febrero de 2012 - 21:51
Hay un error grave en el script para GD. Al final, donde dice imagejpg() debe decir imagejpeg. He estado un buen rato dandole vueltas. De todas formas, gracias por el script. Un saludo
Comentario de Imaginanet - 13 de Febrero de 2012 - 07:13
Ya está solucionado. Gracias.
Comentario de Emiliano - 23 de Julio de 2012 - 17:34
Hola, excelente ejemplo, muchisimas gracias, pero tengo un pequeño problema, no me funciona :(, se que no es problema del script, pero queria saber si me pueden dar una mano. saludos!
Comentario de Imaginanet - 24 de Julio de 2012 - 06:24
Asegúrate de que tu servidor tiene activada la librería GD o instalado imagemagick en caso de que uses éste. También podría pasar que el servidor tengo activado el modo seguro de PHP (safe mode), lo cual podría impedir que ejecutes imagemagick a través de la función passthru. Otra cosa que se me ocurre es que repases las rutas de las imágenes por si has cometido algún error ahí. Fíjate en los mensajes de error que te devuelve el script.
Comentario de Juan - 27 de Abril de 2013 - 08:03
Muchas gracias!!, excelente aportacion!
Comentario de Allan - 24 de Mayo de 2013 - 07:59
Muy buen post pero siento decir que no me funciono :( revise las rutas de los archivos thumb.php, los parametros file y width y no funciono, considere si podria ser por el soporte GD pero se encuentra activo, la verdad no se que hacer, si pueden ayudarme se los agradezco muchisimo
Comentario de Squadron - 20 de Junio de 2013 - 15:30
Hay alguna forma de hacer lo mismo pero de una pagina web, darle al script una URL y que genere al vuelo una miniatura de la web?
Comentario de Valeria - 17 de Julio de 2013 - 13:01
A mi un script asi no me funciona por el memory_limit de mi servidor.... puede ser que no te funcione a ti por ese motivo...
Comentario de bowman - 20 de Agosto de 2013 - 15:12
Funciona perfectamente, muchas gracias.
Comentario de Gilberto - 16 de Octubre de 2013 - 15:08
Funciono perfectamente. Los que dicenque no funciona chequen bien las rutas de archivos. Muchas gracias por comaprtir tu codigo amigo.
Comentario de jose luis - 04 de Abril de 2014 - 18:49
Excelente aporte solo tuve que sacar "." . ya que no entendí que hacía, funcionó perfecto
Comentario de Jhonatan - 19 de Agosto de 2014 - 15:26
Amigo en serio que sufri un poco pero me funcionó, muchas gracias, tambien al comentario de Jose Luis me fué de gran ayuda justo cuando taba por tirar la toalla...
Comentario de Jennifer - 27 de Octubre de 2014 - 21:26
Muchas gracias por el código!! tuve que eliminar el / que esta antes de thumb. quedando asi <code> <img src="thumb.php?file=/public/image1.png&width=100" alt="miniatura" /> </code> en vez de <code> <img src="/thumb.php?file=/public/image1.png&width=100" alt="miniatura" /> </code> Así como le sirvió a "jose luis" eliminar el punto. (es cuestión de ruta directorio) Excelente aporte (Y)
Comentario de Juan - 07 de Enero de 2015 - 18:58
Que bien me vino esto! Muchísimas gracias. Tuve que quitar las / y los "." para que me funcione correctamente como se mencionó en los comentarios anteriores. Saludos.
Comentario de javier - 19 de Junio de 2017 - 21:04
gracias por el aporte.
Ha habido un error en el envío
Comentario enviado. Será revisado por la moderación antes de ser publicado.

Deja tu comentario

Tu nombre:
Tu email:
Tu comentario: