Title: wp_calculate_image_srcset
Published: December 9, 2015
Last modified: February 24, 2026

---

# wp_calculate_image_srcset( int[] $size_array, string $image_src, array $image_meta, int $attachment_id ): string|false

## In this article

 * [Parameters](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#changelog)
 * [User Contributed Notes](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#user-contributed-notes)

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

A helper function to calculate the image sources to include in a ‘srcset’ attribute.

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

 `$size_array`int[]required

An array of width and height values.

 * `0` int
 * The width in pixels.
 * `1` int
 * The height in pixels.

`$image_src`stringrequired

The `'src'` of the image.

`$image_meta`arrayrequired

The image meta data as returned by ‘[wp_get_attachment_metadata()](https://developer.wordpress.org/reference/functions/wp_get_attachment_metadata/)‘.

`$attachment_id`intoptional

The image attachment ID. Default 0.

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

 string|false The `'srcset'` attribute value. False on error or when only one source
exists.

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

    ```php
    function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) {
    	/**
    	 * Pre-filters the image meta to be able to fix inconsistencies in the stored data.
    	 *
    	 * @since 4.5.0
    	 *
    	 * @param array  $image_meta    The image meta data as returned by 'wp_get_attachment_metadata()'.
    	 * @param int[]  $size_array    {
    	 *     An array of requested width and height values.
    	 *
    	 *     @type int $0 The width in pixels.
    	 *     @type int $1 The height in pixels.
    	 * }
    	 * @param string $image_src     The 'src' of the image.
    	 * @param int    $attachment_id The image attachment ID or 0 if not supplied.
    	 */
    	$image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id );

    	if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) {
    		return false;
    	}

    	$image_sizes = $image_meta['sizes'];

    	// Get the width and height of the image.
    	$image_width  = (int) $size_array[0];
    	$image_height = (int) $size_array[1];

    	// Bail early if error/no width.
    	if ( $image_width < 1 ) {
    		return false;
    	}

    	$image_basename = wp_basename( $image_meta['file'] );

    	/*
    	 * WordPress flattens animated GIFs into one frame when generating intermediate sizes.
    	 * To avoid hiding animation in user content, if src is a full size GIF, a srcset attribute is not generated.
    	 * If src is an intermediate size GIF, the full size is excluded from srcset to keep a flattened GIF from becoming animated.
    	 */
    	if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) {
    		$image_sizes[] = array(
    			'width'  => $image_meta['width'],
    			'height' => $image_meta['height'],
    			'file'   => $image_basename,
    		);
    	} elseif ( str_contains( $image_src, $image_meta['file'] ) ) {
    		return false;
    	}

    	// Retrieve the uploads sub-directory from the full size image.
    	$dirname = _wp_get_attachment_relative_path( $image_meta['file'] );

    	if ( $dirname ) {
    		$dirname = trailingslashit( $dirname );
    	}

    	$upload_dir    = wp_get_upload_dir();
    	$image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname;

    	/*
    	 * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain
    	 * (which is to say, when they share the domain name of the current request).
    	 */
    	if ( is_ssl() && ! str_starts_with( $image_baseurl, 'https' ) ) {
    		/*
    		 * Since the `Host:` header might contain a port, it should
    		 * be compared against the image URL using the same port.
    		 */
    		$parsed = parse_url( $image_baseurl );
    		$domain = isset( $parsed['host'] ) ? $parsed['host'] : '';

    		if ( isset( $parsed['port'] ) ) {
    			$domain .= ':' . $parsed['port'];
    		}

    		if ( $_SERVER['HTTP_HOST'] === $domain ) {
    			$image_baseurl = set_url_scheme( $image_baseurl, 'https' );
    		}
    	}

    	/*
    	 * Images that have been edited in WordPress after being uploaded will
    	 * contain a unique hash. Look for that hash and use it later to filter
    	 * out images that are leftovers from previous versions.
    	 */
    	$image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash );

    	/**
    	 * Filters the maximum image width to be included in a 'srcset' attribute.
    	 *
    	 * @since 4.4.0
    	 *
    	 * @param int   $max_width  The maximum image width to be included in the 'srcset'. Default '2048'.
    	 * @param int[] $size_array {
    	 *     An array of requested width and height values.
    	 *
    	 *     @type int $0 The width in pixels.
    	 *     @type int $1 The height in pixels.
    	 * }
    	 */
    	$max_srcset_image_width = apply_filters( 'max_srcset_image_width', 2048, $size_array );

    	// Array to hold URL candidates.
    	$sources = array();

    	/**
    	 * To make sure the ID matches our image src, we will check to see if any sizes in our attachment
    	 * meta match our $image_src. If no matches are found we don't return a srcset to avoid serving
    	 * an incorrect image. See #35045.
    	 */
    	$src_matched = false;

    	/*
    	 * Loop through available images. Only use images that are resized
    	 * versions of the same edit.
    	 */
    	foreach ( $image_sizes as $image ) {
    		$is_src = false;

    		// Check if image meta isn't corrupted.
    		if ( ! is_array( $image ) ) {
    			continue;
    		}

    		// If the file name is part of the `src`, we've confirmed a match.
    		if ( ! $src_matched && str_contains( $image_src, $dirname . $image['file'] ) ) {
    			$src_matched = true;
    			$is_src      = true;
    		}

    		// Filter out images that are from previous edits.
    		if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
    			continue;
    		}

    		/*
    		 * Filters out images that are wider than '$max_srcset_image_width' unless
    		 * that file is in the 'src' attribute.
    		 */
    		if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) {
    			continue;
    		}

    		// If the image dimensions are within 1px of the expected size, use it.
    		if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) {
    			// Add the URL, descriptor, and value to the sources array to be returned.
    			$source = array(
    				'url'        => $image_baseurl . $image['file'],
    				'descriptor' => 'w',
    				'value'      => $image['width'],
    			);

    			// The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030.
    			if ( $is_src ) {
    				$sources = array( $image['width'] => $source ) + $sources;
    			} else {
    				$sources[ $image['width'] ] = $source;
    			}
    		}
    	}

    	/**
    	 * Filters an image's 'srcset' sources.
    	 *
    	 * @since 4.4.0
    	 *
    	 * @param array  $sources {
    	 *     One or more arrays of source data to include in the 'srcset'.
    	 *
    	 *     @type array $width {
    	 *         @type string $url        The URL of an image source.
    	 *         @type string $descriptor The descriptor type used in the image candidate string,
    	 *                                  either 'w' or 'x'.
    	 *         @type int    $value      The source width if paired with a 'w' descriptor, or a
    	 *                                  pixel density value if paired with an 'x' descriptor.
    	 *     }
    	 * }
    	 * @param array $size_array     {
    	 *     An array of requested width and height values.
    	 *
    	 *     @type int $0 The width in pixels.
    	 *     @type int $1 The height in pixels.
    	 * }
    	 * @param string $image_src     The 'src' of the image.
    	 * @param array  $image_meta    The image meta data as returned by 'wp_get_attachment_metadata()'.
    	 * @param int    $attachment_id Image attachment ID or 0.
    	 */
    	$sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id );

    	// Only return a 'srcset' value if there is more than one source.
    	if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) {
    		return false;
    	}

    	$srcset = '';

    	foreach ( $sources as $source ) {
    		$srcset .= str_replace( ' ', '%20', $source['url'] ) . ' ' . $source['value'] . $source['descriptor'] . ', ';
    	}

    	return rtrim( $srcset, ', ' );
    }
    ```

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

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

 [apply_filters( ‘max_srcset_image_width’, int $max_width, int[] $size_array )](https://developer.wordpress.org/reference/hooks/max_srcset_image_width/)

Filters the maximum image width to be included in a ‘srcset’ attribute.

 [apply_filters( ‘wp_calculate_image_srcset’, array $sources, array $size_array, string $image_src, array $image_meta, int $attachment_id )](https://developer.wordpress.org/reference/hooks/wp_calculate_image_srcset/)

Filters an image’s ‘srcset’ sources.

 [apply_filters( ‘wp_calculate_image_srcset_meta’, array $image_meta, int[] $size_array, string $image_src, int $attachment_id )](https://developer.wordpress.org/reference/hooks/wp_calculate_image_srcset_meta/)

Pre-filters the image meta to be able to fix inconsistencies in the stored data.

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

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

Helper function to test if aspect ratios for two images match.

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

Retrieves uploads directory information.

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

Gets the attachment path relative to the upload directory.

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

Determines if SSL is used.

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

Sets the scheme for a URL.

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

i18n-friendly version of basename().

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

Appends a trailing slash.

  | 
| [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.

  |

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

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

Creates image tag markup for a custom header image.

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

Adds ‘srcset’ and ‘sizes’ attributes to an existing ‘img’ element.

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

Retrieves the value for an image attachment’s ‘srcset’ attribute.

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

Gets an HTML img element representing an image attachment.

  |

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

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

## 󠀁[User Contributed Notes](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#user-contributed-notes)󠁿

 1.  [Skip to note 2 content](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/?output_format=md#comment-content-1369)
 2.   [Joe McGill](https://profiles.wordpress.org/joemcgill/)  [  10 years ago  ](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/#comment-1369)
 3. [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_calculate_image_srcset%2F%23comment-1369)
    Vote results for this note: 7[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_calculate_image_srcset%2F%23comment-1369)
 4. Note that only image sizes matching the aspect ratio for the original image will
    be returned by `[wp_calculate_image_srcset()](https://developer.wordpress.org/reference/functions/wp_calculate_image_srcset/)`
    since the `srcset` attribute is only meant to be used for resolution switching,
    not changing aspect ratios at different viewport widths (often referred to as the“
    art direction” use case). See: [http://usecases.responsiveimages.org/](http://usecases.responsiveimages.org/).
 5.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_calculate_image_srcset%2F%3Freplytocom%3D1369%23feedback-editor-1369)

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