Thay đổi nén JPEG tùy thuộc vào kích thước hình ảnh


8

Ngắn. Tôi muốn hình ảnh '' lớn 'được nén 90% và' trung bình 'là 60%. Có nhiều bạn biết, đôi khi những hình ảnh lớn hơn bị nén cao, nhưng những hình ảnh nhỏ khác thì không.

Chức năng này cho phép lấy mẫu lại tất cả các hình ảnh jpg

function custom_jpg_compression($args) {
    return 90;
}
add_filter('jpeg_quality', 'custom_jpg_compression');

Làm thế nào để lọc theo kích thước hình ảnh?

Câu trả lời:


11

Một bộ lọc rất đặc biệt

Bộ jpeg_qualitylọc là một bộ lọc thực sự đặc biệt: Nó được sử dụng trong ba trường hợp khác nhau và bạn sẽ sử dụng đối số thứ hai để xác định, nếu bạn muốn sử dụng bộ lọc hay không.

Đừng để nó làm mọi thứ

Vấn đề chính của một bộ lọc đặc biệt như vậy là nó có thể kích hoạt các hành động sau này, nếu bạn không gỡ bỏ nó - cho phép nó chạy sau lần kiểm tra đầu tiên. Vì vậy, chúng ta cần phải có một bộ lọc khác bên trong wp_save_image_file()để kiểm tra xem chúng ta có muốn thay đổi việc nén hay không. Để vô hiệu hóa nó cho một quá trình lưu khác, chúng tôi loại bỏ nó ngay trước khi thay đổi nén.

Đứa trẻ

Điều thực sự kỳ lạ là, WP sử dụng mức nén mặc định 90% (giảm 10% chất lượng) cho mỗi quy trình lưu. Điều này có nghĩa là, mỗi khi bạn tải lên / cắt / chỉnh sửa một hình ảnh, bạn sẽ giảm chất lượng của nó ... đó là một nỗi đau cho những hình ảnh không phải là tốt nhất, khi bạn tải chúng lên (kiểm tra nó với một hình ảnh có nhiều màu đỏ với một nền tương phản cao). Nhưng ... Điều thực sự gọn gàng là, bạn có thể thay đổi hành vi này. Vì vậy, bạn muốn thay đổi nén, nhưng tăng chất lượng - tốt hơn nhiều so với lõi cho phép - cùng một lúc.

/**
 * Alter the image compression, depending on case
 * 
 * @param  int $compression
 * @param  string $case
 * @return int $compression
 */
function wpse58600_custom_jpg_compression_cb( $compression, $case )
{
    global $size_switch;

    // Should only fire once - don't leave it in for later cases
    remove_filter( current_filter(), __FUNCTION__ );

    // Alter the compression, depending on the case
    switch ( $case )
    {
        case( 'edit_image' ) :
            // We only add the compression, if the switch triggered,
            // which means, that the size is smaller, than set in the main function.
            // 60 is the percentage value, that gets added as compression to the smaller images.
            $compression = $size_switch ? 60 : 100;
            break;

        case( 'image_resize' ) :
            // Better leave it on 100% for resize
            $compression = 100;
            break;

        case( 'wp_crop_image' ) :
            // Better leave it on 100% for crop
            // We already compressed it on the camera, the desktop/handheld device 
            // and the server previously. That's enough so far.
            $compression = 100;
            break;
    }

    return $compression;
}

/**
 * Alter the compression for JPEG mime type images
 * Checks for a specific min size of the image, before altering it
 * 
 * @param  string $image
 * @param  int $post_id 
 * @return string $image
 */
function wpse58600_custom_jpg_compression( $image, $post_id )
{
    global $size_switch;
    $size_switch = false;

    // Define the size, that stops adding a compression
    $trigger_size = 641;

    // Get the sizes
    $size_x = imagesx( $image );
    $size_y = imagesy( $image );

    // Add the filter only in case
    if ( $trigger_size < $size_x )
    {
        $size_switch = true;
    }
    add_filter( 'jpeg_quality', 'wpse58600_custom_jpg_compression_cb', 20, 2 );

    return $image;
}
add_filter( 'image_save_pre', 'wpse58600_custom_jpg_compression', 20, 2 );

EDIT: Sau một cuộc thảo luận ngắn với @toscho, ông chỉ ra rằng toàn bộ cuộc gọi lại có thể được giảm xuống như sau:

function wpse58600_custom_jpg_compression_cb( $compression, $case )
{
    // Should only fire once - don't leave it in for later cases
    remove_filter( current_filter(), __FUNCTION__ );

    return ( $GLOBALS['size_switch'] && 'edit_image' === $case ) ? 60 : 100;
}

Khi tôi rút mã ra khỏi plugin tôi đang làm việc, tôi cần switchthêm cài đặt. Tôi cũng phải lưu ý rằng tôi không sử dụng globalplugin trong plugin của mình, vì đó là cách tiếp cận OOP. Mã bạn có thể đọc ↑ ở trên, chủ yếu là mã được giảm và thay đổi từ plugin, có một chút dư thừa và có nghĩa là để giải thích cho những người đọc sau này và vẫn hoạt động. Nếu bạn muốn sử dụng nó làm plugin, bạn có thể thực hiện một số tối ưu hóa tùy thuộc vào trường hợp sử dụng cá nhân của bạn.


Ghi chú:

Từ một số điều tra về các nhiệm vụ khác nhau, tôi nhận thấy rằng nhiều $cases được kích hoạt theo các bước sau:

  • Xoay: edit-image» image-resize(1 × sau cho bất kỳ kích thước nào bạn chọn - Hình thu nhỏ, v.v.)
  • Gương: edit-image» image-resize(-" -)

Điều này có nghĩa là, gọi lại bộ lọc cho jpeq_qualitysẽ kích hoạt 2 × để xoay / phản chiếu hình ảnh và + 1 × cho bất kỳ kích thước bổ sung nào bạn thêm. Vì vậy, nếu bạn có ít hơn 100%, nó sẽ giảm chất lượng hai lần. Tôi đã nghiên cứu rất nhiều về chủ đề này, nhưng tôi vẫn không hoàn toàn chắc chắn, chức năng chính xác nào gây ra hành vi này.


Bạn đã nhận được tôi, print_r / var_dump không hoạt động. Làm thế nào tôi có thể đầu ra?
DarkGhostHunter

Sử dụng echo '<pre>'.var_export( $image, true ).'</pre>';. Đặt exit;sau nó để nó không bị bỏ qua khi tải lại trang, v.v.
kaiser

chết tiệt, bị lạc trong rừng - tôi không thể thấy nó in ở đâu. Tôi có mã đó trước khi trả về $ image;
DarkGhostHunter

Thêm nó ngay khi bắt đầu wpse58600_custom_jpg_compression()hàm.
kaiser

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.