WordPress encourages changing themes with ease and every theme uses images differently, so why is it so hard to change image dimensions?
You’ve got a WordPress site, the three standard image sizes are usually good enough for inserting in content but maybe your theme registers some more for featured posts, galleries or sliders. If you change theme and end up with a wider content area or new uses for added image sizes, or even if you just change the media settings yourself, you’ll find out that the existing images aren’t handled too gracefully.
The solution in core is to find the nearest larger image size and just shrink it in the browser to fit the new dimensions. This is bad for performance, because you’re loading an image bigger than you need and it doesn’t crop the image to the new dimensions, so you’ll often get unwanted white space.
The issue was well defined in 2010 by Victor Teixeira and subsequent contributor repos, more recently by Eric Lewis. I’ve put the code for my approach up in gist, but I’ll go through the process below. I got some feedback from Eric who made an earlier submission to patch the core approach. I agree that it should be core, because currently the idea of drag-and-drop theming doesn’t float if you require a manual step (with a plugin no less) to adapt your media to new themes. Still, I’m satisfied with resolving it with some drop in code for now.
Other options on the table – using external PHP libraries, replacing functions with custom template tags, the proposed patches or using plugins that regenerate images manually – work with some success but don’t satisfyall the following ideal (imo) criteria.
- Regenerate images automatically when required by the current theme.
- Don’t require a plugin to manage media and extra images sizes.
- Don’t use depreciated or custom image processing functions.
- Let WordPress handle creation, paths, error checking, library detection.
- Allow other filters to still apply (don’t bypass filtered functions).
- Keep generated sizes in meta to avoid orphan files in uploads folder.
- Can be disabled/removed without errors or changing anything else.
You don’t need to configure or enable anything, just download the snippet and either paste or require it in your theme functions file.
WITH THEME SPECIFIC SIZE
add_image_size( ‘Feature Image’, 565, 337, true );
in theme functions.php
the_post_thumbnail( ‘Feature Image’ );
in template file
WITH ON-THE-FLY DIMENSIONS
the_post_thumbnail( array( 565, 337 ) );
in template file ( will create a new named size called ‘565×337′ )
Read the comments in the gist for better notes. Basically, I filtered the image_downsize function to:
- Firstly, exit the process as soon as possible if it’s not required.
- If asked for custom dimensions, make a name to remember them by.
- If another named size matches the dimensions, use it instead.
- If nothing matching the size exists, use image_make_intermediate_size to generate one. Its the same core function used when uploading images.
- The new file will be put with the old one, so we don’t need to do anything tricky to find the media path, which was a weakness of vt_resize and caused bugs with some servers.
- Save the new size to meta, so it won’t look again. Other approaches checked file exists, which would no doubt be slower and prone to error if naming patterns change.
The one thing it doesn’t do is remove the generated images when they’re not needed any more. That could happen in a cron function, but it does make it possible by registering the dynamically generated images in the attachment’s meta. So a cleanup function could compare the meta sizes of all media with the current defined image sizes and delete any that are no longer needed.
Get in touch if you’re using this, or if you think it’s the dumbest thing ever.
I’ve had some feedback regarding using `srcset` and `sizes` attributes in image to resolve showing different sizes and I wanted to clarify this isn’t meant to address responsive or retina ready image sizes, but it could help with that.
e.g. you may have an image source set in your theme that shows an image in 500×500 or 1000×1000 depending on device resolution. If you change theme and the layout and images are smaller, maybe your device resolution options are now 300×300, 600×600. WP will still load the media that was sized for the previous theme and downsize it in browser to the new dimensions. Using dynamic image sizing, it would load an image with the exact dimensions required, always.
As for responsive source sets, this plugin is apparently moving into core at some point: https://wordpress.org/plugins/ricg-responsive-images/
That wouldn’t replace the need for dynamic resizing of the attachment files though, because you may still need to generate the different versions provided in the source set if the image was uploaded before you set the dimensions.
If you see the coments on GitHub, daltonrooney found some performance enhancements and made a fork of the gist. I’m going to incorporate what I can, but their approach doesn’t generate new images for named sizes, which wouldn’t help in the case of a theme change with existing media library, so I’ll have to do some tweaking there.