Установите сжатие JPEG для определенных пользовательских размеров изображения

8

Я использую различные пользовательские размеры изображений (by add_image_size), и я установил свое сжатие JPEG на 30% с помощью этого фильтра:

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

Если я не ошибаюсь, приведенный выше код сжимает все мои нестандартные размеры изображения на 30%. Теперь для двух моих имен нестандартных размеров splash1и splash2я хочу установить сжатие на 80%. Как это возможно?

Или же, исключите эти размеры изображения из фильтра 30% сжатия.

Аманда герцог
источник

Ответы:

9

Функции 'jpeg_quality'ловушки фильтра принимают два аргумента: $jpeg_qualityи $functionкоторая является функцией из ловушки фильтра, запускается и может быть либо image_resizeили wp_crop_image. Таким образом, нет возможности выборочно установить качество .jpegизображения в соответствии с размером изображения с помощью этой функции фильтра фильтра.

Тем не менее, вы все еще можете подключиться к более позднему действию в процессе загрузки вложений и отрегулировать .jpegкачество изображения загруженных изображений в этой точке в соответствии с их конкретным размером в соответствии с вашими потребностями. Сначала установите jpeg_qualityмаксимальное значение, чтобы сохранить исходное качество изображения, затем подключите к added_post_metaдействию ловушку (которая запускается в конце вставки метаданных вложения), чтобы отрегулировать качество следующим образом:

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

Приведенный выше код повлияет только на вновь загруженные изображения. Если вы хотите обновить качество ранее загруженных изображений, вы можете использовать register_activation_hookплагины. Создайте новый php-файл в wp-content/pluginsкаталоге и назовите его как хотите ( update-jpeg-quality.phpнапример) и добавьте в него следующий код:

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

Теперь зайдите на страницу плагинов и нажмите activateна Update JPEG Qualityплагин. Это зациклит все ваши ранее загруженные .jpegизображения и отрегулирует их качество в соответствии со значениями и условиями, указанными в плагине. Затем вы можете безопасно деактивировать и удалить этот плагин. Пожалуйста , проверьте на тестирование среды первой перед нанесением на производственную площадку .

Ахмад М
источник
Это очень интересный ответ. Как мне добавить 'splash1' и 'splash2' в оператор IF ?: if ($ size == 'splash') ...
Аманда Дьюк
1
@AmandaDuke: Вы можете расширить ifутверждение на elseif. Смотрите мое обновление.
Ахмад М
2
@ Ахмад, в твоем коде есть ошибка. При загрузке изображения, если он меньше , чем размеры самого маленького нестандартного размера изображения, а затем появляется эта ошибка: Invalid argument supplied for foreach(). Таким образом, в основном, когда пользовательское изображение не создается, появляется ошибка. Вы знаете, как решить эту проблему?
Аманда Герцог
1
@AmandaDuke Спасибо за указание на это. Эта ошибка происходит, потому что $attach_meta['sizes']ожидается, что это будет массив, в то время как в этом случае это не так. В большинстве случаев это должно произойти, и это может произойти, только если у нас нет пользовательских размеров изображения, и мы не указываем размеры изображения по умолчанию в Настройках -> Настройки мультимедиа . Чтобы обезопасить себя и убедиться , что у нас есть массив можно добавить проверку перед передачей его в foreachпетлю: if (is_array($attach_meta['sizes'])). Пожалуйста, смотрите обновленный код.
Ахмад М
1
@AmandaDuke: оба блока кода были обновлены. Первый блок был раньше: if ( $post->post_mime_type == 'image/jpeg' )а теперь этоif ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
Ахмад М