Es posible que nos encontremos con la necesidad de optimizar las imágenes en un sitio ya sea porque son enormes o su peso supera lo que consideramos que debería ser o simplemente tenemos muchas imágenes en nuestro ordenador y queremos que queden en un tamaño estándar ya que no necesitamos usarlas para impresión.

En la red podemos encontrar distintos programas o incluso webs que nos pueden ayudar a hacerlo e manera sencilla pero su forma de trabajar hace que sea tedioso cuando tenemos una gran cantidad de archivos, aun así para pocas imágenes nos pueden ayudar.

Reducir imágenes online gratis

Una solución rápida es utilizar servicios en la web para reducir las imágenes que necesitemos, existen servicios gratuitos o limitados como los siguientes:

  • I Love IMG: contiene distintas herramientas para comprimir y reducir el tamaño de nuestras imágenes, muchas de sus opciones están limitadas para usar de forma gratuita.
  • Bulk Image resizer: Permite cambiar el tamaño de nuestras imágenes.

Como las anteriores existen bastantes opciones pero veamos como hacerlo sin necesidad de entrar a un sitio externo utilizando la librería GD.

¿Qué es PHP GD?

PHP GD es una extensión de PHP que permite la manipulación de imágenes directamente desde scripts PHP. GD significa “Graphic Draw” y proporciona funciones para leer, manipular imágenes, incluyendo la creación de imágenes desde cero, dibujar formas simples como líneas y rectángulos, aplicar filtros a imágenes, y combinar imágenes entre otras operaciones.

Es especialmente útil en aplicaciones web para generar gráficos dinámicos, miniaturas de imágenes, captchas, y cualquier otra manipulación de imágenes que se necesite realizar en tiempo real desde un servidor PHP.

Entre los formatos soportados por PHP GD se puede trabajar con archivos JPG, PNG, GIF, XBM, XBMP y WebP.

Más información de GD

Escalando, reduciendo peso y cambiando el formato de imágenes con PHP GD

Usemos un ejemplo práctico y vamos paso a paso, en mi caso tengo un sitio de información de películas que abandoné por bastante tiempo pero al revisar la base de datos y los archivos encontré muchos puntos a mejorar sobre todo el peso de las imágenes y para ello necesito reducir 1530 imágenes tanto de tamaño como de peso y aprovecharé para cambiar a un formato más ligero como es WebP en una calidad de 70.

Anteriormente realicé las consultas necesarias para obtener la ubicación de las imágenes y poder hacer una consulta para obtener la información y hacer el cambio a su nuevo nombre de archivo utilizando un loop ahora necesito crear una función que me permita generar esas nuevas imágenes y las almacene en otra ubicación con un formato similar /año/mes/ para no tener demasiados archivos por carpeta, con lo anterior empecemos:

  1. Obtenemos el nombre y ruta del archivo de imagen que vamos a modificar (lo podemos hacer desde una base de datos o explorando una carpeta en modo local).
  2. Utilizaremos getimagesize para obtener la información de la imagen ya que la utilizaremos para calcular la proporción final y el tipo de archivo.
  3. Ya con el tipo de archivo listo utilizaremos la función necesaria, en mi caso solamente utilizaba imágenes en jpg, png o finalmente webp, agregaré la opción de gif por si acaso; para ello utilizaremos las funciones imagecreatefromwebp, imagecreatefrompng, imagecreatefromjpeg, imagecreatefromgif, dependiendo de cada caso, las funciones anteriores crean una nueva imagen a partir de un fichero o de una URL, para el ejemplo utilizaremos jpg.
  4. Agregamos como variable el nuevo tamaño máximo que usaremos en este caso solamente el ancho ya que los posters son en formato retrato pero para usarlo de otra forma pueden agregar también el alto máximo que consideren y hacer el cálculo con una regla de 3 y redondeando el número aun número entero utilizando la función round.
  5. Generamos una imágen base utilizando imagecreatetruecolor con el tamaño final calculado.
  6. Generamos una nueva imagen con el tamaño nuevo utilizando imagecopyresampled
  7. Definimos la ubicación final y lo salvamos ahí utilizando imagewebp con una calidad de 70

Haremos primero lo anterior y continuaremos después de ver el resultado utilizando el siguiente código:

$urlarchivo = "http://localhost/uploads/2013/10/poster_la_noche_del_demonio_2.jpg";
echo $urlarchivo."<br/>";
$infoarchivo = getimagesize($urlarchivo);
print_r($infoarchivo);
$anchooriginal = $infoarchivo[0];
$altooriginal = $infoarchivo[1];
if($infoarchivo['mime']=='image/jpg' or $infoarchivo['mime']=='image/jpeg' or $infoarchivo['mime']=='image/pjpeg'){
        $nuevaimagen = imagecreatefromjpeg($urlarchivo);
}
$nuevow = "600";
if($anchooriginal > $nuevow){
        
    $altonuevo = round($altooriginal*$nuevow/$anchooriginal);
    $anchonuevo = $nuevow;
   }else{
        $altonuevo = $altooriginal;
        $anchonuevo = $anchooriginal;
   }
    echo "<br/>Alto final:".$anchonuevo."<br/>";
    echo "Alto final:".$altonuevo."<br/>";
   }
$base = imagecreatetruecolor( $altonuevo, $anchonuevo );
imagecopyresampled($base,$nuevaimagen,0,0,0,0,$anchonuevo,$altonuevo,$anchooriginal,$altooriginal); 
$nuevaubicacion = 'nombrearchivo.webp';

    if($infoarchivo['mime']=='image/jpg' or $infoarchivo['mime']=='image/jpeg' or $infoarchivo['mime']=='image/pjpeg'){
        $nuevaimagen = imagewebp($base,$nuevaubicacion,70);
    }

Lenguaje del código: PHP (php)

Con el código anterior ya podrás tener una nueva imagen guardada en la carpeta donde uses el código con el nombre seleccionado, a partir de esto debes hacer las modificaciones necesarias para que funcione correctamente de acuerdo a tus necesidades.

Para un uso más sencillo lo convertiré en una función que nos ayudará a reducir archivos jpg y de paso convertirlos a Webp a partir de la url del archivo:

//función para reducir imágenes jpg y convertirlas a webp
function convertirimagen($urlimagen, $anchomax, $nuevonombreimmagen){
    $infoarchivo = getimagesize($urlimagen);
    $anchooriginal = $infoarchivo[0];
    $altooriginal = $infoarchivo[1];
         if($infoarchivo['mime']=='image/jpg' or $infoarchivo['mime']=='image/jpeg' or $infoarchivo['mime']=='image/pjpeg'){
         $nuevaimagen = imagecreatefromjpeg($urlimagen);
         }
        $nuevow = $anchomax;
        if($anchooriginal > $nuevow){
        $altonuevo = round($altooriginal*$nuevow/$anchooriginal);
        $anchonuevo = $nuevow;
        }
        else
        {$altonuevo = $altooriginal;
        $anchonuevo = $anchooriginal;
        }
    $base = imagecreatetruecolor( $altonuevo, $anchonuevo );
    imagecopyresampled($base,$nuevaimagen,0,0,0,0,$anchonuevo,$altonuevo,$anchooriginal,$altooriginal);
    $nuevaubicacion = '/';
    if($infoarchivo['mime']=='image/jpg' or $infoarchivo['mime']=='image/jpeg' or $infoarchivo['mime']=='image/pjpeg'){
    $nuevaimagen = imagewebp($base,$nuevaubicacion,70);
    }
    return $nuevaimagen;
    }
    //llamamos nuestra función
    $url = 'https://dominio.tld/imagen.jpg';
    $ancho = "600";
    $nuevonombre = "imagen.webp";
    convertirimagen($url, $ancho, $nuevonombre);
Lenguaje del código: PHP (php)

Si tienes alguna duda o necesitas ayuda con tu proyecto no dudes en hacer contacto.