Atur kompresi JPEG untuk ukuran gambar khusus tertentu

8

Saya menggunakan berbagai ukuran gambar khusus (oleh add_image_size) dan saya telah menetapkan kompresi JPEG saya menjadi 30% dengan filter ini:

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

Jika saya tidak salah, kode di atas mengkompres semua ukuran gambar khusus saya dengan 30%. Sekarang, untuk dua ukuran gambar khusus saya bernama splash1dan splash2, saya ingin mengatur kompresi ke 80%. Bagaimana ini mungkin?

Atau sebagai alternatif, kecualikan ukuran gambar tersebut dari filter kompresi 30%.

Amanda Duke
sumber

Jawaban:

9

The 'jpeg_quality'fungsi filter yang kait menerima dua argumen: $jpeg_qualitydan $functionyang merupakan fungsi dari dalam hook filter dipecat dan dapat berupa image_resizeatau wp_crop_image. Jadi tidak ada cara untuk secara selektif mengatur kualitas .jpeggambar sesuai dengan ukuran gambar dari fungsi hook filter ini.

Namun, Anda masih dapat menghubungkan ke tindakan kait selanjutnya dalam proses mengunggah lampiran dan menyesuaikan .jpegkualitas gambar dari gambar yang diunggah pada saat itu sesuai dengan ukuran spesifik mereka yang sesuai dengan kebutuhan Anda. Pertama-tama atur jpeg_qualityke maksimum untuk mempertahankan kualitas gambar asli, lalu kait ke added_post_metakait tindakan (yang ditembakkan di akhir memasukkan metadata lampiran) untuk menyesuaikan kualitas, sebagai berikut:

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

Kode di atas hanya akan memengaruhi gambar yang baru saja diunggah. Jika Anda ingin memperbarui kualitas gambar yang diunggah sebelumnya, Anda dapat menggunakan register_activation_hookplugin. Buat file php baru di wp-content/pluginsdirektori dan beri nama apa pun yang Anda suka ( update-jpeg-quality.phpmisalnya) dan tambahkan kode berikut ke dalamnya:

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

Sekarang kunjungi halaman Plugin Anda dan tekan activatedari Update JPEG QualityPlugin. Ini akan mengulang semua .jpeggambar yang diunggah sebelumnya dan menyesuaikan kualitasnya sesuai dengan nilai dan ketentuan yang Anda tentukan dalam plugin. Kemudian Anda dapat dengan aman menonaktifkan dan menghapus plugin ini. Silakan uji lingkungan pengujian terlebih dahulu sebelum mendaftar ke lokasi produksi .

Ahmad M
sumber
Ini jawaban yang sangat menarik. Bagaimana cara menambahkan 'splash1' dan 'splash2' ke pernyataan IF ?: if ($ size == 'splash') ...
Amanda Duke
1
@AmandaDuke: Anda dapat memperpanjang ifpernyataan dengan elseif. Lihat pembaruan saya.
Ahmad M
2
@Ahmad ada bug di kode Anda. Ketika meng-upload gambar, jika lebih kecil dari dimensi ukuran gambar kustom terkecil, maka kesalahan ini muncul: Invalid argument supplied for foreach(). Jadi pada dasarnya, ketika tidak ada gambar khusus yang dibuat, kesalahan muncul. Apakah Anda tahu cara memperbaiki masalah ini?
Amanda Duke
1
@AmandaDuke Terima kasih telah menunjukkannya. Kesalahan ini terjadi karena $attach_meta['sizes']diharapkan menjadi array sedangkan dalam kasus ini tidak. Dalam kebanyakan kasus seharusnya dan ini hanya dapat terjadi jika kita tidak memiliki ukuran gambar khusus dan kami tidak menentukan ukuran gambar default di Pengaturan -> Pengaturan Media . Agar aman dan memastikan kami memiliki sebuah array kita dapat menambahkan cek sebelum diteruskan ke foreachlingkaran: if (is_array($attach_meta['sizes'])). Silakan lihat kode yang diperbarui.
Ahmad M
1
@AmandaDuke: Kedua blok kode telah diperbarui. Blok pertama adalah sebelumnya: if ( $post->post_mime_type == 'image/jpeg' )dan sekarangif ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
Ahmad M