Définir la compression JPEG pour des tailles d'image personnalisées spécifiques

8

J'utilise différentes tailles d'image personnalisées (par add_image_size) et j'ai défini ma compression JPEG à 30% avec ce filtre:

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

Si je ne me trompe pas, le code ci-dessus comprime toutes mes tailles d'image personnalisées avec 30%. Maintenant, pour deux de mes tailles d'image personnalisées nommées splash1et splash2, je veux définir la compression à 80%. Comment est-ce possible?

Ou bien, excluez ces tailles d'image du filtre de compression à 30%.

Amanda Duke
la source

Réponses:

9

Les 'jpeg_quality'fonctions de hook de filtre acceptent deux arguments: $jpeg_qualityet $functionquelle est la fonction de l'intérieur du hook de filtre est déclenchée et peut être soit image_resizeou wp_crop_image. Il n'y a donc aucun moyen de définir sélectivement la qualité des .jpegimages en fonction de la taille de l'image à partir de cette fonction de crochet de filtre.

Cependant, vous pouvez toujours vous accrocher à un crochet d'action ultérieur dans le processus de téléchargement de pièces jointes et ajuster la .jpegqualité d'image des images téléchargées à ce stade en fonction de leur taille spécifique en fonction de vos besoins. Réglez d'abord le jpeg_qualityau maximum pour préserver la qualité de l'image d'origine, puis accrochez-vous au crochet d' added_post_metaaction (qui est déclenché à la fin de l'insertion des métadonnées de pièce jointe) pour ajuster la qualité, comme suit:

// 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);
            }
        }
    }
}

Le code ci-dessus affectera uniquement les images nouvellement téléchargées. Si vous souhaitez mettre à jour la qualité des images précédemment téléchargées, vous pouvez utiliser register_activation_hookdes plugins. Créez un nouveau fichier php dans le wp-content/pluginsrépertoire et nommez-le comme vous le souhaitez ( update-jpeg-quality.phppar exemple) et ajoutez-lui le code suivant:

<?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);
        }
    }
}
?>

Maintenant, visitez votre page Plugins et cliquez sur activatele Update JPEG Qualityplugin. Cela parcourra toutes vos .jpegimages précédemment téléchargées et ajustera leur qualité en fonction des valeurs et des conditions que vous spécifiez dans le plugin. Ensuite, vous pouvez désactiver et supprimer ce plugin en toute sécurité. Veuillez d'abord tester l'environnement de test avant de postuler sur le site de production .

Ahmad M
la source
Ceci est une réponse très intéressante. Comment ajouter à la fois 'splash1' et 'splash2' à l'instruction IF?: If ($ size == 'splash') ...
Amanda Duke
1
@AmandaDuke: Vous pouvez prolonger la ifdéclaration de elseif. Voir ma mise à jour.
Ahmad M
2
@Ahmad il y a un bug dans votre code. Lors du téléchargement d' une image, si elle est plus petite que les dimensions de la plus petite taille d'image personnalisée, cette erreur apparaît: Invalid argument supplied for foreach(). Donc, fondamentalement, lorsqu'aucune image personnalisée n'est créée, l'erreur apparaît. Savez-vous comment résoudre ce problème?
Amanda Duke
1
@AmandaDuke Merci d'avoir signalé cela. Cette erreur se produit car $attach_meta['sizes']devrait être un tableau alors que dans ce cas, il ne l'est pas. Dans la plupart des cas, cela devrait et cela ne peut se produire que si nous n'avons pas de tailles d'image personnalisées et que nous ne spécifions pas les tailles d'image par défaut dans Paramètres -> Paramètres du support . Pour être sûr et assurez - vous que nous avons un tableau , nous pouvons ajouter un chèque avant de le transmettre à la foreachboucle: if (is_array($attach_meta['sizes'])). Veuillez voir le code mis à jour.
Ahmad M
1
@AmandaDuke: Les deux blocs de code ont été mis à jour. Le premier bloc était avant: if ( $post->post_mime_type == 'image/jpeg' )et maintenant c'estif ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
Ahmad M