Title: wp_create_image_subsizes
Published: November 12, 2019
Last modified: February 24, 2026

---

# wp_create_image_subsizes( string $file, int $attachment_id ): array

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#wp--skip-link--target)

Creates image sub-sizes, adds the new data to the image meta `sizes` array, and 
updates the image metadata.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#description)󠁿

Intended for use after an image is uploaded. Saves/updates the image metadata after
each sub-size is created. If there was an error, it is added to the returned image
metadata array.

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#parameters)󠁿

 `$file`stringrequired

Full path to the image file.

`$attachment_id`intrequired

Attachment ID to process.

## 󠀁[Return](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#return)󠁿

 array The image attachment meta data.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#source)󠁿

    ```php
    function wp_create_image_subsizes( $file, $attachment_id ) {
    	$imagesize = wp_getimagesize( $file );

    	if ( empty( $imagesize ) ) {
    		// File is not an image.
    		return array();
    	}

    	// Default image meta.
    	$image_meta = array(
    		'width'    => $imagesize[0],
    		'height'   => $imagesize[1],
    		'file'     => _wp_relative_upload_path( $file ),
    		'filesize' => wp_filesize( $file ),
    		'sizes'    => array(),
    	);

    	// Fetch additional metadata from EXIF/IPTC.
    	$exif_meta = wp_read_image_metadata( $file );

    	if ( $exif_meta ) {
    		$image_meta['image_meta'] = $exif_meta;
    	}

    	/**
    	 * Filters the "BIG image" threshold value.
    	 *
    	 * If the original image width or height is above the threshold, it will be scaled down. The threshold is
    	 * used as max width and max height. The scaled down image will be used as the largest available size, including
    	 * the `_wp_attached_file` post meta value.
    	 *
    	 * Returning `false` from the filter callback will disable the scaling.
    	 *
    	 * @since 5.3.0
    	 *
    	 * @param int    $threshold     The threshold value in pixels. Default 2560.
    	 * @param array  $imagesize     {
    	 *     Indexed array of the image width and height in pixels.
    	 *
    	 *     @type int $0 The image width.
    	 *     @type int $1 The image height.
    	 * }
    	 * @param string $file          Full path to the uploaded image file.
    	 * @param int    $attachment_id Attachment post ID.
    	 */
    	$threshold = (int) apply_filters( 'big_image_size_threshold', 2560, $imagesize, $file, $attachment_id );

    	/*
    	 * If the original image's dimensions are over the threshold,
    	 * scale the image and use it as the "full" size.
    	 */
    	$scale_down = false;
    	$convert    = false;

    	if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) {
    		// The image will be converted if needed on saving.
    		$scale_down = true;
    	} else {
    		// The image may need to be converted regardless of its dimensions.
    		$output_format = wp_get_image_editor_output_format( $file, $imagesize['mime'] );

    		if (
    			is_array( $output_format ) &&
    			array_key_exists( $imagesize['mime'], $output_format ) &&
    			$output_format[ $imagesize['mime'] ] !== $imagesize['mime']
    		) {
    			$convert = true;
    		}
    	}

    	if ( $scale_down || $convert ) {
    		$editor = wp_get_image_editor( $file );

    		if ( is_wp_error( $editor ) ) {
    			// This image cannot be edited.
    			return $image_meta;
    		}

    		if ( $scale_down ) {
    			// Resize the image. This will also convet it if needed.
    			$resized = $editor->resize( $threshold, $threshold );
    		} elseif ( $convert ) {
    			// The image will be converted (if possible) when saved.
    			$resized = true;
    		}

    		$rotated = null;

    		// If there is EXIF data, rotate according to EXIF Orientation.
    		if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) {
    			$resized = $editor->maybe_exif_rotate();
    			$rotated = $resized; // bool true or WP_Error
    		}

    		if ( ! is_wp_error( $resized ) ) {
    			/*
    			 * Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
    			 * This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
    			 */
    			if ( $scale_down ) {
    				$saved = $editor->save( $editor->generate_filename( 'scaled' ) );
    			} elseif ( $convert ) {
    				// Pass an empty string to avoid adding a suffix to converted file names.
    				$saved = $editor->save( $editor->generate_filename( '' ) );
    			} else {
    				$saved = $editor->save();
    			}

    			if ( ! is_wp_error( $saved ) ) {
    				$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );

    				// If the image was rotated update the stored EXIF data.
    				if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
    					$image_meta['image_meta']['orientation'] = 1;
    				}
    			} else {
    				// TODO: Log errors.
    			}
    		} else {
    			// TODO: Log errors.
    		}
    	} elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) {
    		// Rotate the whole original image if there is EXIF data and "orientation" is not 1.
    		$editor = wp_get_image_editor( $file );

    		if ( is_wp_error( $editor ) ) {
    			// This image cannot be edited.
    			return $image_meta;
    		}

    		// Rotate the image.
    		$rotated = $editor->maybe_exif_rotate();

    		if ( true === $rotated ) {
    			// Append `-rotated` to the image file name.
    			$saved = $editor->save( $editor->generate_filename( 'rotated' ) );

    			if ( ! is_wp_error( $saved ) ) {
    				$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );

    				// Update the stored EXIF data.
    				if ( ! empty( $image_meta['image_meta']['orientation'] ) ) {
    					$image_meta['image_meta']['orientation'] = 1;
    				}
    			} else {
    				// TODO: Log errors.
    			}
    		}
    	}

    	/*
    	 * Initial save of the new metadata.
    	 * At this point the file was uploaded and moved to the uploads directory
    	 * but the image sub-sizes haven't been created yet and the `sizes` array is empty.
    	 */
    	wp_update_attachment_metadata( $attachment_id, $image_meta );

    	$new_sizes = wp_get_registered_image_subsizes();

    	/**
    	 * Filters the image sizes automatically generated when uploading an image.
    	 *
    	 * @since 2.9.0
    	 * @since 4.4.0 Added the `$image_meta` argument.
    	 * @since 5.3.0 Added the `$attachment_id` argument.
    	 *
    	 * @param array $new_sizes     Associative array of image sizes to be created.
    	 * @param array $image_meta    The image meta data: width, height, file, sizes, etc.
    	 * @param int   $attachment_id The attachment post ID for the image.
    	 */
    	$new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );

    	return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id );
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-admin/includes/image.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-admin/includes/image.php#L240)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-admin/includes/image.php#L240-L413)

## 󠀁[Hooks](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#hooks)󠁿

 [apply_filters( ‘big_image_size_threshold’, int $threshold, array $imagesize, string $file, int $attachment_id )](https://developer.wordpress.org/reference/hooks/big_image_size_threshold/)

Filters the “BIG image” threshold value.

 [apply_filters( ‘intermediate_image_sizes_advanced’, array $new_sizes, array $image_meta, int $attachment_id )](https://developer.wordpress.org/reference/hooks/intermediate_image_sizes_advanced/)

Filters the image sizes automatically generated when uploading an image.

## 󠀁[Related](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_get_image_editor_output_format()](https://developer.wordpress.org/reference/functions/wp_get_image_editor_output_format/)`wp-includes/media.php` |

Determines the output format for the image editor.

  | 
| [wp_filesize()](https://developer.wordpress.org/reference/functions/wp_filesize/)`wp-includes/functions.php` |

Wrapper for PHP filesize with filters and casting the result as an integer.

  | 
| [wp_getimagesize()](https://developer.wordpress.org/reference/functions/wp_getimagesize/)`wp-includes/media.php` |

Allows PHP’s getimagesize() to be debuggable when necessary.

  | 
| [wp_get_registered_image_subsizes()](https://developer.wordpress.org/reference/functions/wp_get_registered_image_subsizes/)`wp-includes/media.php` |

Returns a normalized list of all currently registered image sub-sizes.

  | 
| [_wp_image_meta_replace_original()](https://developer.wordpress.org/reference/functions/_wp_image_meta_replace_original/)`wp-admin/includes/image.php` |

Updates the attached file and image meta data when the original image was edited.

  | 
| [_wp_make_subsizes()](https://developer.wordpress.org/reference/functions/_wp_make_subsizes/)`wp-admin/includes/image.php` |

Low-level function to create image sub-sizes.

  | 
| [wp_read_image_metadata()](https://developer.wordpress.org/reference/functions/wp_read_image_metadata/)`wp-admin/includes/image.php` |

Gets extended image metadata, exif or iptc as available.

  | 
| [wp_get_image_editor()](https://developer.wordpress.org/reference/functions/wp_get_image_editor/)`wp-includes/media.php` |

Returns a [WP_Image_Editor](https://developer.wordpress.org/reference/classes/wp_image_editor/) instance and loads file into it.

  | 
| [wp_update_attachment_metadata()](https://developer.wordpress.org/reference/functions/wp_update_attachment_metadata/)`wp-includes/post.php` |

Updates metadata for an attachment.

  | 
| [_wp_relative_upload_path()](https://developer.wordpress.org/reference/functions/_wp_relative_upload_path/)`wp-includes/post.php` |

Returns relative path to an uploaded file.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [is_wp_error()](https://developer.wordpress.org/reference/functions/is_wp_error/)`wp-includes/load.php` |

Checks whether the given variable is a WordPress Error.

  |

[Show 7 more](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#)

| Used by | Description | 
| [wp_update_image_subsizes()](https://developer.wordpress.org/reference/functions/wp_update_image_subsizes/)`wp-admin/includes/image.php` |

If any of the currently registered image sub-sizes are missing, create them and update the image meta data.

  | 
| [wp_generate_attachment_metadata()](https://developer.wordpress.org/reference/functions/wp_generate_attachment_metadata/)`wp-admin/includes/image.php` |

Generates attachment meta data and create image sub-sizes for images.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/?output_format=md#changelog)󠁿

| Version | Description | 
| [5.3.0](https://developer.wordpress.org/reference/since/5.3.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_create_image_subsizes%2F)
before being able to contribute a note or feedback.