Custom Image Size Generator
Register custom WordPress image sizes with the right crop behaviour, and optionally offer them in the editor's size dropdown.
<?php
/**
* Custom image sizes.
*/
/**
* Registers the sizes.
*
* Only uploads made after this exists get the new files. Images already in
* the library keep the sizes they had, so regenerate after adding one.
*/
function my_theme_image_sizes() {
add_image_size( 'card-thumb', 480, 320, true );
// No crop: the image is scaled to fit inside these bounds.
add_image_size( 'hero-wide', 1600, 0 );
}
add_action( 'after_setup_theme', 'my_theme_image_sizes' );
/**
* Adds the sizes to the dropdown in the editor.
*
* Registering a size does not offer it to editors. This is what does.
*
* @param array $sizes Size name to label.
* @return array
*/
function my_theme_image_size_names( $sizes ) {
$sizes['card-thumb'] = __( 'Card thumbnail', 'my-theme' );
return $sizes;
}
add_filter( 'image_size_names_choose', 'my_theme_image_size_names' );
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Register the image sizes your theme actually uses, with the crop behaviour you meant, and put the ones editors need into the size dropdown.
How to use
- Add one size per place the theme renders an image at a fixed size. Two sizes that differ by 20 pixels are one size.
- Decide crop per size. Cropped means exactly those dimensions, with the edges cut off; uncropped scales the image to fit inside them.
- Use 0 for the dimension you do not care about.
1600by0means “no wider than 1600, any height”. - Tick the editor box only for sizes an author should be able to choose. Registering a size does not offer it to anyone.
- Regenerate thumbnails after adding a size. Existing uploads are not touched.
Example
Two sizes, one cropped for cards and one bounded for heroes:
function acme_image_sizes() {
add_image_size( 'card-thumb', 480, 320, true );
// No crop: the image is scaled to fit inside these bounds.
add_image_size( 'hero-wide', 1600, 0 );
}
add_action( 'after_setup_theme', 'acme_image_sizes' );
add_image_size() on any hook later than after_setup_theme is registered too late for some of the media pipeline, which is why the size sometimes works in the editor and not on upload.
Pitfalls
- Adding a size does nothing for images already in the library. They fall back to the nearest existing size, which is usually the full one.
- Every registered size is another file written on every upload, plus the WebP or AVIF variants on newer WordPress. Five extra sizes on a photo site is a real cost in disk and upload time.
- Removing a size later does not delete the generated files. They stay on disk until something cleans them up.
- A cropped size crops from the centre by default, which decapitates portraits. Pass an array such as
array( 'center', 'top' )when the subject is at the top. add_image_size()registers the size;image_size_names_chooseis what puts it in the editor dropdown. Doing only the first is the most common mistake here.- A size larger than the uploaded image is not generated. WordPress never upscales, so
the_post_thumbnail( 'hero-wide' )can silently return a smaller file. - Sizes are theme code. Switching themes leaves the files behind and the new theme knows nothing about the names.
srcsetis built from the registered sizes, so removing the defaults makes the responsive image set smaller. That is the trade you are making.
Compatibility
add_image_size() and image_size_names_choose have been stable since WordPress 2.9 and 3.3. The crop position array needs WordPress 3.9. intermediate_image_sizes filters the sizes WordPress generates and works in every current version; medium_large arrived in 4.4, the 1536 and 2048 sizes in 5.3. The generated code targets PHP 7.0 and up, and the tool runs entirely in your browser.
Frequently asked questions
Why is my new size not being used?
How do I regenerate existing images?
wp media regenerate with WP-CLI, or a regeneration plugin. Both rebuild every registered size for every attachment.Crop or no crop?
Why does my size not appear in the editor?
image_size_names_choose is what adds it to the dropdown, and the generated code includes it.Should I remove the default sizes?
srcset, so removing them makes responsive images less responsive.