Set JPEG compression for specific custom image sizes

The 'jpeg_quality' filter hook functions accept two arguments: $jpeg_quality and $function which is the function from within the filter hook is fired and can be either image_resize or wp_crop_image. So there is no way to selectively set the quality of .jpeg images according to image size from this filter hook function.

However, you still can hook to a later action hook in the process of uploading attachments and adjust the .jpeg image quality of uploaded images at that point according to thier specific size to suit your needs. First set the jpeg_quality to the maximum to preserve the original image quality, then hook to added_post_meta action hook (which is fired at the end of inserting attachment metadata`) to adjust the quality, as follow:

// 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'] . "https://wordpress.stackexchange.com/" . $pathinfo['dirname'];

            foreach ($attach_meta['sizes'] as $size => $value) {

                $image = $dir . "https://wordpress.stackexchange.com/" . $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);
            }
        }
    }
}

The above code will affect the newly uploaded images only. If you want to update the quality of previously uploaded images, you can utilize register_activation_hook of plugins. Create a new php file in wp-content/plugins directory and name it whatever you like (update-jpeg-quality.php for example) and add the following code to it:

<?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'] . "https://wordpress.stackexchange.com/" . $pathinfo['dirname'];

        foreach ($attach_meta['sizes'] as $size => $value) {

            $image = $dir . "https://wordpress.stackexchange.com/" . $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);
        }
    }
}
?>

Now visit your Plugins page and hit activate of the Update JPEG Quality plugin. This will loop through all your previously uploaded .jpeg images and adjust their quality according to the values and conditions you specify in the plugin. Then you can safely deactivate and delete this plugin. Please test on testing environment first before applying to production site.

Leave a Comment