This hook is particularly beneficial for those aiming to optimize server disk space. If you frequently upload large images to your WordPress site, you may encounter the challenge of expanding disk space over time. While some web hosts might not find this problematic, if you’re hosted on Rocket.net, additional charges may apply for the space you consume.
While one solution is to delete the original files, this approach, while effective, comes with significant drawbacks. The main issue is that if you need to regenerate new sizes for the images, you won’t be able to do so. Generating new images becomes necessary when the site adopts different sizes or, for instance, when you need to modify or add a watermark to a photo.
After uploading a large photo and, after WordPress creates a smaller set from it, we delete the oversized original and assign the largest copy as the original. By doing so, we get rid of unnecessary large files, but also keep the ability to generate new sizes if needed.
And all of this can be done with the following hook:
function osw_replace_uploaded_image($image_data) {
// Do nothing if the image is small
if (!isset($image_data['sizes']['large'])) return $image_data;
// Paths to images and the large image
$upload_dir = wp_upload_dir();
$uploaded_image_location = $upload_dir['basedir'] . '/' . $image_data['file'];
// For new images
$large_image_location = $upload_dir['path'] . '/' . $image_data['sizes']['large']['file'];
// Delete the uploaded image
unlink($uploaded_image_location);
// Rename the large copy
rename($large_image_location, $uploaded_image_location);
// Update metadata
$image_data['width'] = $image_data['sizes']['large']['width'];
$image_data['height'] = $image_data['sizes']['large']['height'];
unset($image_data['sizes']['large']);
return $image_data;
}
// Attach the function to the necessary hook
add_filter('wp_generate_attachment_metadata', 'osw_replace_uploaded_image');
A small addition to the code above. To make it work you need to disable scaling of large images in WordPress. For large photos/images, it creates another size and marks it with the suffix “_scaled” in the name. We don’t need this extra action, so we disable it:
add_filter( 'big_image_size_threshold', '__return_false' );
Important! The code above works only for new images. If you need to replace/remove the original for images already loaded into the media library, then the line $large_image_location = … should be replaced with the following code.
$current_subdir = substr( $image_data['file'], 0, strrpos( $image_data['file'], '/' ) );
$large_image_location = $upload_dir['basedir'] . '/' . $current_subdir . '/' . $image_data['sizes']['large']['file'];
In this way, you can replace an uploaded image with a smaller copy. In this way, you can safely delete the original image and leave its largest copy instead. Best of luck and good optimization!
Leave a Reply