Optimización masiva de imágenes en Wordpress con script de PHP

Sergi Rodríguez  
22-07-2024 14:23  
7 minutos de lectura  

Introducción

Ya sabrás que la mayoría de usuarios de wordpress no se preocupan muchos por ciertos "detalles" técnicos como la optimización de las imágenes. Normalmente Wordpress hace una gestión muy buena de las imágenes de la Biblioteca de Medios, generando diferentes copias de la imagen subida por el usuario, para usar una u otra en función del contexto y tamaño de pantalla del visitante. Lo cuál agiliza mucho la navegación de los visitantes.

Sin embargo, cuando una web empieza a tener varios años de uso y con un ritmo de publicación intensa de artículos, el problema empieza a ser el aumento considerable del espacio de almacenamiento de esas imágenes, y no tanto las copias optimizadas generadas de forma automática por wordpress sino las imágenes originales, que wordpress NO ELIMINA.

Entonces, queriendo hacer algo al respecto de esta situación (pueden ser varios Gb de almacenamiento! que aparte de ocupar espacio ralentiza y sobredimensiona los backups) decidí hacer un simple script de PHP que ejecutado desde el terminal del servidor para optimizar miles de imágenes en un par de minutos con un solo comando.

Nota anecdótica: la IA de Claude fue la artífice del script, obviamente guiada por un atinado "prompt", y un par de iteraciones para dotar al script de algunos extras interesantes.

Detalles del script

Qué hace el script:

  • revisar recursivamente todo un directorio
  • busca las imágenes JPG, JPEG y PNG
  • redimensiona las imágenes que sobrepasen cierta resolución
  • opcionalmente comprime las imágenes

Las opciones de ejecución (para hacerllo más seguro) se definen al inicio del script:

$dir = '/ruta/al/directorio'; // Directorio a procesar
$maxWidth = 1920; // Ancho máximo
$maxHeight = 1080; // Alto máximo
$jpegQuality = 85; // Calidad JPEG (0-100)
$pngCompression = 9; // Nivel de compresión PNG (0-9)
$processAllImages = false; // False para procesar solo las que exceden las dimensiones máximas

Puedes descargarlo aquí: optimizar-imagenes-recursivamente.php.zip

// Configuración
$dir = '/ruta/al/directorio'; // Directorio a procesar
$maxWidth = 1920; // Ancho máximo
$maxHeight = 1080; // Alto máximo
$jpegQuality = 78; // Calidad JPEG (0-100)
$pngCompression = 9; // Nivel de compresión PNG (0-9)
$processAllImages = false; // Establecer en true para procesar todas las imágenes, false para procesar solo las que exceden las dimensiones máximas

// Función para optimizar una imagen
function optimizeImage($file) {
    global $maxWidth, $maxHeight, $jpegQuality, $pngCompression, $processAllImages;

    $image = new Imagick($file);
    $origWidth = $image->getImageWidth();
    $origHeight = $image->getImageHeight();

    $needsRescaling = ($origWidth > $maxWidth || $origHeight > $maxHeight);

    if ($needsRescaling || $processAllImages) {
        // Redimensionar si excede las dimensiones máximas
        if ($needsRescaling) {
            $image->resizeImage($maxWidth, $maxHeight, Imagick::FILTER_LANCZOS, 1, true);
        }

        // Optimizar según el tipo de imagen
        $format = strtolower($image->getImageFormat());
        if ($format === 'jpeg' || $format === 'jpg') {
            $image->setImageCompression(Imagick::COMPRESSION_JPEG);
            $image->setImageCompressionQuality($jpegQuality);
        } elseif ($format === 'png') {
            $image->setImageCompression(Imagick::COMPRESSION_ZIP);
            $image->setImageCompressionQuality($pngCompression * 10); // Imagick usa escala 0-100
        }

        // Guardar la imagen optimizada
        $image->writeImage($file);
        echo "Imagen procesada: " . $file . PHP_EOL;
    } else {
        echo "Imagen no procesada (dimensiones dentro de los límites): " . $file . PHP_EOL;
    }

    $image->clear();
}

// Función para procesar un directorio recursivamente
function processDirectory($dir) {
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($files as $file) {
        if ($file->isFile()) {
            $extension = strtolower($file->getExtension());
            if (in_array($extension, ['jpg', 'jpeg', 'png'])) {
                optimizeImage($file->getPathname());
            }
        }
    }
}

// Ejecutar el proceso
processDirectory($dir);

echo "Proceso completado." . PHP_EOL;

Eficacia de la optimización de las imágenes

Aumentará la eficacia si:

  • tienes imágenes demasiado grandes
  • o decides poner un máximo de resolución ajustado (por ejemplo 1200px por 800px)
  • calibras el script para una compresión JPEG por debajo de 75

Ejemplo: a mí el directorio wp-content/uploads con unas mil imágenes ha pasado de 886Mb a 582Mb, es decir, un ahorro del 34%, usando compresión JPG 78 y resolución máxima de 1920x1080 px.

Aviso a navegantes

  • Si defines $processAllImages = true; entonces el script abrirá todas las imágenes y las volvera a guardar. Este es un proceso que produce una pérdida de calidad de imagen CADA VEZ QUE SE EJCUTA. Es decir, idealmente no lo ejecutes DOS VECES en la misma imagen!
     
  • En cambio, sí puedes configurar sin riesgos una ejecución automática con esa opción en FALSE, y no hay problema con ello, porqué "lo único" que hará en cada ejecución es controlar que nunca haya imágenes con "demasiada resolución", pero las otras imágenes no las tocará 😁
Etiquetas : wordpress | ia

Comentarios 0   Visitas 25  

  Comentarios


Añada su comentario:

Comentario:
Nombre:
(pregunta anti-robots)

Enviar

DÍGANOS QUÉ NECESITA

¡¡ Le respondemos antes de 24h !!
Puede dejarnos su teléfono.

Puede rellenar el formulario (pulsar botón derecha) o bien aquí tiene nuestros datos de contacto.

(pregunta anti-robots)

  Enviar

Revisar consentimientos a cookies