Establecer compresión JPEG para tamaños de imagen personalizados específicos


8

Utilizo varios tamaños de imagen personalizados (por add_image_size) y configuré mi compresión JPEG al 30% con este filtro:

function jpeg_quality_callback($arg) {
   return (int)30;
}
add_filter('jpeg_quality', 'jpeg_quality_callback');

Si no me equivoco, el código anterior comprime todos mis tamaños de imagen personalizados con un 30%. Ahora, para dos de mis tamaños de imagen personalizados nombrados splash1y splash2, quiero establecer la compresión al 80%. ¿Cómo es esto posible?

O, alternativamente, excluya esos tamaños de imagen del filtro de compresión del 30%.

Respuestas:


9

Las 'jpeg_quality'funciones de enlace de filtro aceptan dos argumentos: $jpeg_qualityy $functioncuál es la función desde dentro del enlace de filtro se activa y puede ser image_resizeo wp_crop_image. Por lo tanto, no hay forma de establecer selectivamente la calidad de las .jpegimágenes de acuerdo con el tamaño de la imagen desde esta función de enlace de filtro.

Sin embargo, aún puede engancharse a un gancho de acción posterior en el proceso de carga de archivos adjuntos y ajustar la .jpegcalidad de imagen de las imágenes cargadas en ese punto de acuerdo con su tamaño específico para satisfacer sus necesidades. Primero configure jpeg_qualityal máximo para preservar la calidad de imagen original, luego enganche a gancho de added_post_metaacción (que se activa al final de insertar los metadatos del archivo adjunto ') para ajustar la calidad, de la siguiente manera:

// set the quality to maximum
add_filter('jpeg_quality', create_function('$quality', 'return 100;'));

add_action('added_post_meta', 'ad_update_jpeg_quality', 10, 4);

function ad_update_jpeg_quality($meta_id, $attach_id, $meta_key, $attach_meta) {

    if ($meta_key == '_wp_attachment_metadata') {

        $post = get_post($attach_id);

        if ($post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes'])) {

            $pathinfo = pathinfo($attach_meta['file']);
            $uploads = wp_upload_dir();
            $dir = $uploads['basedir'] . '/' . $pathinfo['dirname'];

            foreach ($attach_meta['sizes'] as $size => $value) {

                $image = $dir . '/' . $value['file'];
                $resource = imagecreatefromjpeg($image);

                if ($size == 'spalsh') {
                    // set the jpeg quality for 'spalsh' size
                    imagejpeg($resource, $image, 100);
                } elseif ($size == 'spalsh1') {
                    // set the jpeg quality for the 'splash1' size
                    imagejpeg($resource, $image, 30);
                } else {
                    // set the jpeg quality for the rest of sizes
                    imagejpeg($resource, $image, 10);
                }

                // or you can skip a paticular image size
                // and set the quality for the rest:
                // if ($size == 'splash') continue;

                imagedestroy($resource);
            }
        }
    }
}

El código anterior afectará solo a las imágenes recién cargadas. Si desea actualizar la calidad de las imágenes cargadas previamente, puede utilizar register_activation_hookcomplementos. Cree un nuevo archivo php en el wp-content/pluginsdirectorio y asígnele el nombre que desee ( update-jpeg-quality.phppor ejemplo) y agregue el siguiente código:

<?php
/*
Plugin Name: Update JPEG Quality
Plugin URI: http://wordpress.stackexchange.com/questions/74103/set-jpeg-compression-for-specific-custom-image-sizes
Description: This plugin will change the jpeg image quality according to its size.
Author: Ahmad M
Version: 1.0
Author URI: http://wordpress.stackexchange.com/users/12961/ahmad-m
*/

register_activation_hook(__FILE__, 'ad_modify_jpeg_quality');

function ad_modify_jpeg_quality() {

    $attachments = get_posts(array(
        'numberposts' => -1,
        'post_type' => 'attachment',
        'post_mime_type' => 'image/jpeg'
    ));

    if (empty($attachments)) return;

    $uploads = wp_upload_dir();

    foreach ($attachments as $attachment) {

        $attach_meta = wp_get_attachment_metadata($attachment->ID);
        if (!is_array($attach_meta['sizes'])) break;

        $pathinfo = pathinfo($attach_meta['file']);
        $dir = $uploads['basedir'] . '/' . $pathinfo['dirname'];

        foreach ($attach_meta['sizes'] as $size => $value) {

            $image = $dir . '/' . $value['file'];
            $resource = imagecreatefromjpeg($image);

            if ($size == 'spalsh') {
                // set the jpeg quality for 'spalsh' size
                imagejpeg($resource, $image, 100);
            } elseif ($size == 'spalsh1') {
                // set the jpeg quality for the 'splash1' size
                imagejpeg($resource, $image, 30);
            } else {
                // set the jpeg quality for the rest of sizes
                imagejpeg($resource, $image, 10);
            }

            imagedestroy($resource);
        }
    }
}
?>

Ahora visite su página de Complementos y presione activateel Update JPEG Qualitycomplemento. Esto recorrerá todas sus .jpegimágenes cargadas previamente y ajustará su calidad de acuerdo con los valores y condiciones que especifique en el complemento. Luego puede desactivar y eliminar este complemento de forma segura. Pruebe primero el entorno de prueba antes de aplicar al sitio de producción .


Esta es una respuesta muy interesante. ¿Cómo agrego 'splash1' y 'splash2' a la declaración IF ?: if ($ size == 'splash') ...
Amanda Duke

1
@AmandaDuke: Puedes extender la ifdeclaración por elseif. Mira mi actualización.
Ahmad M

2
@ Ahmad hay un error en tu código. Al cargar una imagen, si es menor que las dimensiones del tamaño de la imagen a medida más pequeña, a continuación, aparece este error: Invalid argument supplied for foreach(). Básicamente, cuando no se crea una imagen personalizada, aparece el error. ¿Sabes cómo solucionar este problema?
Amanda Duke

1
@AmandaDuke Gracias por señalar eso. Este error ocurre porque $attach_meta['sizes']se espera que sea una matriz, mientras que en este caso no lo es. En la mayoría de los casos, debería y esto solo puede suceder si no tenemos tamaños de imagen personalizados y no especificamos los tamaños de imagen predeterminados en Configuración -> Configuración de medios . Para estar seguro y asegurarnos de que tenemos una matriz podemos añadir un cheque antes de pasarlo al foreachbucle: if (is_array($attach_meta['sizes'])). Por favor vea el código actualizado.
Ahmad M

1
@AmandaDuke: Ambos bloques de código han sido actualizados. El primer bloque fue antes: if ( $post->post_mime_type == 'image/jpeg' )y ahora esif ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
Ahmad M
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.