Stellen Sie die JPEG-Komprimierung für bestimmte benutzerdefinierte Bildgrößen ein

8

Ich verwende verschiedene benutzerdefinierte Bildgrößen (von add_image_size) und habe meine JPEG-Komprimierung mit diesem Filter auf 30% eingestellt:

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

Wenn ich mich nicht irre, komprimiert der obige Code alle meine benutzerdefinierten Bildgrößen mit 30%. Für zwei meiner benutzerdefinierten Bildgrößen mit dem Namen splash1und splash2möchte ich die Komprimierung auf 80% einstellen. Wie ist das möglich?

Alternativ können Sie diese Bildgrößen vom 30% -Komprimierungsfilter ausschließen.

Amanda Duke
quelle

Antworten:

9

Die 'jpeg_quality'Filter-Hook-Funktionen akzeptieren zwei Argumente: $jpeg_qualityund $functionwelche Funktion aus dem Filter-Hook heraus ausgelöst wird, kann entweder image_resizeoder sein wp_crop_image. Mit .jpegdieser Filter-Hook-Funktion können Sie die Qualität von Bildern nicht selektiv entsprechend der Bildgröße einstellen .

Sie können jedoch beim Hochladen von Anhängen immer noch eine Verbindung zu einem späteren Aktions-Hook herstellen und die .jpegBildqualität der hochgeladenen Bilder an diesem Punkt entsprechend ihrer spezifischen Größe an Ihre Anforderungen anpassen . Stellen Sie zuerst jpeg_qualitydas Maximum ein, um die ursprüngliche Bildqualität zu erhalten, und hängen Sie dann an den added_post_metaAktionshaken (der am Ende des Einfügens von Anhangsmetadaten ausgelöst wird), um die Qualität wie folgt anzupassen:

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

Der obige Code wirkt sich nur auf die neu hochgeladenen Bilder aus. Wenn Sie die Qualität zuvor hochgeladener Bilder aktualisieren möchten, können Sie register_activation_hookPlugins verwenden. Erstellen Sie eine neue PHP-Datei im wp-content/pluginsVerzeichnis und benennen Sie sie wie Sie möchten ( update-jpeg-quality.phpzum Beispiel) und fügen Sie den folgenden Code hinzu:

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

Besuchen Sie nun Ihre Plugins-Seite und klicken Sie activateauf das Update JPEG QualityPlugin. Dadurch werden alle zuvor hochgeladenen .jpegBilder durchlaufen und ihre Qualität gemäß den im Plugin angegebenen Werten und Bedingungen angepasst. Dann können Sie dieses Plugin sicher deaktivieren und löschen. Bitte testen Sie zuerst die Testumgebung, bevor Sie sich an den Produktionsstandort wenden .

Ahmad M.
quelle
Dies ist eine sehr interessante Antwort. Wie füge ich der IF-Anweisung sowohl 'splash1' als auch 'splash2' hinzu?: If ($ size == 'splash') ...
Amanda Duke
1
@AmandaDuke: Sie können die ifAnweisung um erweitern elseif. Siehe mein Update.
Ahmad M
2
@ Ahmad, es gibt einen Fehler in Ihrem Code. Wenn beim Hochladen eines Bildes die Abmessungen der kleinsten benutzerdefinierten Bildgröße kleiner sind, wird folgender Fehler angezeigt : Invalid argument supplied for foreach(). Wenn also kein benutzerdefiniertes Bild erstellt wird, wird der Fehler angezeigt. Wissen Sie, wie Sie dieses Problem beheben können?
Amanda Duke
1
@AmandaDuke Danke, dass du darauf hingewiesen hast. Dieser Fehler tritt auf, weil $attach_meta['sizes']erwartet wird, dass es sich um ein Array handelt, in diesem Fall jedoch nicht. In den meisten Fällen sollte dies der Fall sein, und dies kann nur geschehen, wenn wir keine benutzerdefinierten Bildgrößen haben und die Standardbildgrößen nicht unter Einstellungen -> Medieneinstellungen angeben . Um sicher zu gehen und sicherzustellen, dass wir ein Array haben, können wir eine Prüfung hinzufügen, bevor wir sie an die foreachSchleife übergeben : if (is_array($attach_meta['sizes'])). Bitte beachten Sie den aktualisierten Code.
Ahmad M
1
@AmandaDuke: Beide Codeblöcke wurden aktualisiert. Der erste Block war vorher: if ( $post->post_mime_type == 'image/jpeg' )und jetzt ist esif ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
Ahmad M