Đặt nén JPEG cho các kích thước hình ảnh tùy chỉnh cụ thể


8

Tôi sử dụng nhiều kích cỡ hình ảnh tùy chỉnh (theo add_image_size) và tôi đã đặt mức nén JPEG của mình thành 30% với bộ lọc này:

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

Nếu tôi không nhầm, đoạn mã trên sẽ nén tất cả các kích thước hình ảnh tùy chỉnh của tôi với 30%. Bây giờ, đối với hai kích thước hình ảnh tùy chỉnh của tôi được đặt tên splash1splash2, tôi muốn đặt mức nén thành 80%. Sao có thể như thế được?

Hoặc cách khác, loại trừ các kích thước hình ảnh đó khỏi bộ lọc nén 30%.

Câu trả lời:


9

Các 'jpeg_quality'hàm hook của bộ lọc chấp nhận hai đối số: $jpeg_quality$functionđó là hàm từ bên trong hook của bộ lọc được kích hoạt và có thể là image_resizehoặc wp_crop_image. Vì vậy, không có cách nào để chọn lọc chất lượng .jpeghình ảnh theo kích thước hình ảnh từ chức năng móc lọc này.

Tuy nhiên, bạn vẫn có thể móc vào một hook hành động sau này trong quá trình tải lên tệp đính kèm và điều chỉnh .jpegchất lượng hình ảnh của hình ảnh được tải lên tại thời điểm đó theo kích thước cụ thể phù hợp hơn với nhu cầu của bạn. Trước tiên, đặt jpeg_qualitymức tối đa để duy trì chất lượng hình ảnh gốc, sau đó móc vào added_post_metahook hành động (được bắn vào cuối khi chèn siêu dữ liệu đính kèm`) để điều chỉnh chất lượng, như sau:

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

Đoạn mã trên sẽ chỉ ảnh hưởng đến những hình ảnh mới được tải lên. Nếu bạn muốn cập nhật chất lượng của hình ảnh được tải lên trước đó, bạn có thể sử dụng register_activation_hookcác plugin. Tạo một tệp php mới trong wp-content/pluginsthư mục và đặt tên nó là bất cứ thứ gì bạn thích ( update-jpeg-quality.phpví dụ) và thêm đoạn mã sau vào nó:

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

Bây giờ truy cập trang Plugins của bạn và nhấn activatecủa Update JPEG Qualityplugin. Điều này sẽ lặp qua tất cả các .jpeghình ảnh được tải lên trước đó của bạn và điều chỉnh chất lượng của chúng theo các giá trị và điều kiện bạn chỉ định trong plugin. Sau đó, bạn có thể hủy kích hoạt và xóa plugin này một cách an toàn. Vui lòng kiểm tra môi trường thử nghiệm trước khi áp dụng cho trang web sản xuất .


Đây là một câu trả lời rất thú vị. Làm cách nào để thêm cả 'Splash1' và 'Splash2' vào câu lệnh IF?: If ($ size == 'Splash') ...
Amanda Duke

1
@AmandaDuke: Bạn có thể mở rộng iftuyên bố bằng cách elseif. Xem cập nhật của tôi.
Ahmad M

2
@Ahmad có một lỗi trong mã của bạn. Khi tải lên một hình ảnh, nếu nó nhỏ hơn kích thước của kích thước hình ảnh tùy chỉnh nhỏ nhất, thì lỗi này xuất hiện : Invalid argument supplied for foreach(). Vì vậy, về cơ bản, khi không có hình ảnh tùy chỉnh được thực hiện, lỗi xuất hiện. Bạn có biết làm thế nào để khắc phục vấn đề này?
Công tước Amanda

1
@AmandaDuke Cảm ơn bạn đã chỉ ra điều đó. Lỗi này xảy ra bởi vì $attach_meta['sizes']dự kiến ​​là một mảng trong khi trong trường hợp này thì không. Trong hầu hết các trường hợp, điều này chỉ xảy ra và điều này chỉ có thể xảy ra nếu chúng tôi không có kích thước hình ảnh tùy chỉnh chúng tôi không chỉ định kích thước hình ảnh mặc định trong Cài đặt -> Cài đặt phương tiện . Để an toàn và đảm bảo chúng tôi có một mảng, chúng tôi có thể thêm một kiểm tra trước khi chuyển nó vào foreachvòng lặp : if (is_array($attach_meta['sizes'])). Xin vui lòng xem mã cập nhật.
Ahmad M

1
@AmandaDuke: Cả hai khối mã đã được cập nhật. Khối đầu tiên là trước đây: if ( $post->post_mime_type == 'image/jpeg' )và bây giờ làif ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
Ahmad M
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.