How to Define New Image Sizes in WordPress

When you upload an image to the WordPress media library, multiple copies are created in different sizes. WordPress does this because different parts of your site need the same image at different resolutions – a large hero image, a medium thumbnail in a grid, a small widget image, and so on.

Out of the box, WordPress registers six image sizes, and most themes and plugins add more. You can register your own custom sizes, remove ones you don’t need, and control which sizes are generated per content type.

Keep in mind that more image sizes means more files in your uploads directory. Each uploaded image can generate dozens of copies if your theme and plugins register many sizes, consuming disk space and slowing down uploads.

Default Image Sizes in WordPress

WordPress registers six image sizes by default. You can configure three of them under Settings > Media in the admin:

Size Name Default Dimensions Configurable?
thumbnail 150 x 150 (cropped) Yes (Settings > Media)
medium 300 x 300 (max) Yes (Settings > Media)
medium_large 768 x 0 (width only) No (added in WP 4.4 for responsive srcset)
large 1024 x 1024 (max) Yes (Settings > Media)
1536x1536 1536 x 1536 (max) No (added in WP 5.3, 2x medium_large)
2048x2048 2048 x 2048 (max) No (added in WP 5.3, 2x large)
Setting Default Image Sizes in WordPress

WordPress only creates a size when the uploaded image is larger than it, so a 2000-pixel-wide upload gets no 2048x2048 copy. It never upscales.

Since WordPress 5.3, any image wider or taller than 2560 pixels is scaled down to fit within 2560 x 2560. WordPress saves that copy with a -scaled suffix and keeps your original upload.

The scaled-down image will be used as the largest available size. – Justin Ahinon, “Introducing handling of big images in WordPress 5.3”, Make WordPress Core

You can change the threshold with the big_image_size_threshold filter, or return false to turn scaling off:

add_filter( 'big_image_size_threshold', function() {
    return 1920;
} );

Removing Default Image Sizes

If you don’t need certain default sizes, remove them with the intermediate_image_sizes filter. Add this to your functions.php file:

add_filter( 'intermediate_image_sizes', function( $sizes ) {
    return array_diff( $sizes, array( 'medium', 'large' ) );
} );

This prevents WordPress from generating those sizes for every upload. Only remove sizes you’re sure aren’t used by your theme or plugins.

Using Image Sizes in Your Theme

There are two ways to use image sizes:

Through the Admin Interface

When inserting an image into a post, you can select which size to display from the image settings panel. Your custom sizes will appear in the dropdown if you register them with the media library (shown later in this guide).

Using Generated Image Sizes in WordPress

Using Code

When building templates, use WordPress image functions and pass the size name as a parameter:

the_post_thumbnail( 'large' );

$image = wp_get_attachment_image_src( $attachment_id, 'my-custom-size' );

echo get_the_post_thumbnail( $post_id, 'thumbnail' );

echo wp_get_attachment_image( $attachment_id, 'card-thumbnail' );

the_post_thumbnail() and get_the_post_thumbnail() output a featured image. wp_get_attachment_image() outputs any attachment as an <img> tag with srcset, and wp_get_attachment_image_src() returns only the URL and dimensions.

Creating Custom Image Sizes

Adding your own image sizes is a two-step process. The second step is optional.

Step 1: Register the Size with add_image_size

Add this to your functions.php file:

add_action( 'after_setup_theme', function() {
    add_image_size( 'card-thumbnail', 400, 300, true );
    add_image_size( 'hero-banner', 1200, 600, true );
    add_image_size( 'square-medium', 500, 500, true );
} );

The add_image_size() function takes four parameters:

  • Name – a unique slug for your size (e.g., card-thumbnail)
  • Width – the target width in pixels
  • Height – the target height in pixels
  • Crop – true crops to exact dimensions (center by default), false resizes proportionally. You can also pass an array like array( 'left', 'top' ) to control the crop position.

Step 2: Add the Size to the Media Library Dropdown

This step is optional but makes your custom size available in the admin image size selector:

add_filter( 'image_size_names_choose', function( $sizes ) {
    $sizes['card-thumbnail'] = 'Card Thumbnail';
    $sizes['hero-banner']    = 'Hero Banner';
    return $sizes;
} );

After adding this, your custom sizes will appear as options when inserting images into posts.

New image sizes only apply to images uploaded after you register them. Existing images won’t have the new size until you regenerate thumbnails. Use WP-CLI (wp media regenerate) or a plugin like Regenerate Thumbnails to create the new sizes for existing images.

Regenerating Image Sizes

After changing your add_image_size() parameters, existing images still have the old dimensions. You need to regenerate them.

Using WP-CLI

The fastest method. Run from the command line:

wp media regenerate --yes

By default this deletes every existing thumbnail and recreates all registered sizes. To create only the sizes an image is missing, add --only-missing:

wp media regenerate --only-missing --yes

To regenerate only a specific image size:

wp media regenerate --image_size=card-thumbnail --yes

Using a Plugin

If you don’t have command-line access, use the Regenerate Thumbnails plugin. It processes images in batches from the WordPress admin.

Reducing Image Sizes Per Content Type

When your site has multiple custom post types, each with their own image sizes, you can end up generating 20-30 images per upload. You can reduce this by only generating the sizes each content type actually needs:

add_filter( 'intermediate_image_sizes_advanced', function( $sizes, $image_meta, $attachment_id ) {
    $parent = wp_get_post_parent_id( $attachment_id );
    $type   = $parent ? get_post_type( $parent ) : '';

    $allowed_by_type = array(
        'page'      => array( 'thumbnail', 'medium', 'hero-banner' ),
        'portfolio' => array( 'card-thumbnail', 'square-medium' ),
    );

    if ( isset( $allowed_by_type[ $type ] ) ) {
        return array_intersect_key( $sizes, array_flip( $allowed_by_type[ $type ] ) );
    }

    return $sizes;
}, 10, 3 );

The filter reads the post the image was uploaded to, so it works in the block editor and the classic media modal, and it keeps the restriction when you run wp media regenerate. Older snippets that read $_REQUEST['post_id'] do neither: the block editor never sends that field. Images uploaded straight to the Media Library have no parent post, so they still get every size.

How to View Registered Image Sizes

To see all image sizes registered by your theme and plugins, you can use WP-CLI or a quick debug snippet.

With WP-CLI:

wp media image-size

It lists every registered size, WordPress defaults included, with its width, height and crop mode. Or add this temporarily to a template file:

<?php
echo '<pre>';
print_r( wp_get_registered_image_subsizes() );
echo '</pre>';
?>

Remove the debug code after you’ve reviewed the output. This is a development tool, not something to leave on a production site.

FAQs

Common questions about WordPress image sizes:

How many image sizes does WordPress create by default?
WordPress registers six sizes by default: Thumbnail (150x150, cropped), Medium (300x300 max), Medium Large (768px wide, added in WP 4.4 for responsive images), Large (1024x1024 max), and two sizes added in WP 5.3, 1536x1536 and 2048x2048. A size is only created when the upload is larger than it, and themes and plugins can register more, so the count per upload depends on your setup.
What is the big_image_size_threshold filter?
Since WordPress 5.3, any image wider or taller than 2560 pixels is scaled down to fit within that size. WordPress saves the scaled copy with a -scaled suffix and uses it as the main image, and the original upload is kept. You can change this threshold using the big_image_size_threshold filter, or return false to disable scaling entirely.
What does the crop parameter do in add_image_size?
When set to true, the image is cropped to the exact dimensions you specify (center-cropped by default). When false, the image is resized proportionally to fit within the width and height. You can also pass an array like array( 'left', 'top' ) to control the crop anchor position.
Do I need to regenerate thumbnails after adding a new image size?
Yes. New sizes only apply to images uploaded after you register them. To create the new size for existing images, run wp media regenerate via WP-CLI, or use a plugin like Regenerate Thumbnails. By default wp media regenerate deletes and re-creates every size; add --only-missing to generate just the sizes an image is missing.
How can I see what image sizes are registered on my site?
Run wp media image-size via WP-CLI, or temporarily print wp_get_registered_image_subsizes() in a template file. Both show every registered size, WordPress defaults included, with dimensions and crop settings.
Will removing image sizes delete existing image files?
No. Removing a size from the intermediate_image_sizes filter only prevents WordPress from generating that size for future uploads. Files that were already created remain on disk. To delete the leftover files for sizes you no longer register, run wp media regenerate --delete-unknown.

Summary

WordPress generates multiple image sizes for each upload to serve the right resolution in different parts of your site. You can configure the defaults under Settings > Media, register custom sizes with add_image_size(), and remove sizes you don’t need via the intermediate_image_sizes filter.

For sites with many custom post types, generate only the sizes each type actually needs to save disk space. After changing image size parameters, regenerate thumbnails with WP-CLI or a plugin so existing images get the new dimensions.

For more on image optimization, see the guide on optimizing WordPress images for SEO.

Discussion
[  0 Comments  ]

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!