I know that I can use the jpeg_quality
filter like this:
add_filter('jpeg_quality', function($arg){return 75;});
This will reduce the image quality of the images generated during the upload process such as the thumbnail, medium and large image sizes, however the original image is still at the original quailty.
Is there a filter or function I can add that will decrease the image quality of the original image when it’s uploaded?
In general I wouldn’t recommend modifying the original uploaded image files, just in case we might need to re-generate intermediate sizes.
But let’s see if it’s possible 🙂
We can in general let WordPress choose the image editor, that depends on modules like GD or Imagick, through:
$editor = wp_get_image_editor( $file );
but this can return an WP_Error
object, so we better check it with is_wp_error( $editor )
before using it.
It’s useful to let the image editor handle things through methods like set_quality()
and save()
. We can see such an usage example in the Resize Image After Upload plugin, mentioned by @MerchantWeb. This is also used by the core in various ways.
The plugin hooks into the wp_handle_upload
filter to modify the original uploaded jpeg image files, as far as I understand it.
A) We could therefore use something like the following, to modify the quality of the original jpeg image file (to e.g. 90) during uploads:
/**
* A) Modify the quality of original jpeg images to 90, during uploads
*/
add_filter( 'wp_handle_upload', function( $data )
{
if( ! isset( $data['file'] ) || ! isset( $data['type'] ) )
return $data;
// Target jpeg images
if( in_array( $data['type'], [ 'image/jpg', 'image/jpeg' ] ) )
{
// Check for a valid image editor
$editor = wp_get_image_editor( $data['file'] );
if( ! is_wp_error( $editor ) )
{
// Set the new image quality
$result = $editor->set_quality( 90 );
// Re-save the original image file
if( ! is_wp_error( $result ) )
$editor->save( $data['file'] );
}
}
return $data;
} );
but it looks to me that this will also affect all the intermediate sizes, because this runs before they are generated.
B) If we take a look at the media_handle_upload()
function, we might consider hooking into the wp_generate_attachment_metadata
filter instead, to modify the original jpeg image file, after the intermediate sizes have been generated.
Here’s an example (PHP 5.4+):
/**
* B) Modify the quality of original jpeg images to 90, during uploads
*/
add_filter( 'wp_generate_attachment_metadata', function( $metadata, $attachment_id )
{
$file = get_attached_file( $attachment_id );
$type = get_post_mime_type( $attachment_id );
// Target jpeg images
if( in_array( $type, [ 'image/jpg', 'image/jpeg' ] ) )
{
// Check for a valid image editor
$editor = wp_get_image_editor( $file );
if( ! is_wp_error( $editor ) )
{
// Set the new image quality
$result = $editor->set_quality( 90 );
// Re-save the original image file
if( ! is_wp_error( $result ) )
$editor->save( $file );
}
}
return $metadata;
}, 10, 2 );
If we needed to restrict this further, we might wrap this into the wp_handle_upload
hook as well and check for the relevant action context, like wp_handle_upload or sideload.
We might also need to set the quality very low while testing, just to see if it worked 😉
Note: These are only demos, that would need further testing.
Update: Just did some simple testing with an image of our kitchen wall clock. Here we can see that when the full size image is re-saved, with quality 5, then all the intermediate sizes:
- A) are also at low quality.
- B) are not affected.
Here are the combined results:

