Set JPEG compression for specific custom image sizes

I use various custom image sizes (by add_image_size) and I have set my JPEG compression to 30% with this filter:

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

If I am not mistaken, the above code compresses all of my custom image sizes with 30%. Now, for two of my custom image sizes named splash1 and splash2, I want to set the compression to 80%. How is this possible?

Read More

Or alternatively, exclude those image sizes from the 30% compression filter.

Related posts

Leave a Reply

1 comment

  1. 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'] . '/' . $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);
                }
            }
        }
    }
    

    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'] . '/' . $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);
            }
        }
    }
    ?>
    

    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.