* WordPress API for media display.
* Retrieve additional image sizes.
* @global array $_wp_additional_image_sizes
* @return array Additional images size data.
function wp_get_additional_image_sizes() {
global $_wp_additional_image_sizes;
if ( ! $_wp_additional_image_sizes ) {
$_wp_additional_image_sizes = array();
return $_wp_additional_image_sizes;
* Scale down the default size of an image.
* This is so that the image is a better fit for the editor and theme.
* The `$size` parameter accepts either an array or a string. The supported string
* values are 'thumb' or 'thumbnail' for the given thumbnail size or defaults at
* 128 width and 96 height in pixels. Also supported for the string value is
* 'medium', 'medium_large' and 'full'. The 'full' isn't actually supported, but any value other
* than the supported will result in the content_width size or 500 if that is
* Finally, there is a filter named {@see 'editor_max_image_size'}, that will be
* called on the calculated array for width and height, respectively.
* @global int $content_width
* @param int $width Width of the image in pixels.
* @param int $height Height of the image in pixels.
* @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array
* of width and height values in pixels (in that order). Default 'medium'.
* @param string $context Optional. Could be 'display' (like in a theme) or 'edit'
* (like inserting into an editor). Default null.
* An array of width and height values.
* @type int $0 The maximum width in pixels.
* @type int $1 The maximum height in pixels.
function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) {
$_wp_additional_image_sizes = wp_get_additional_image_sizes();
$context = is_admin() ? 'edit' : 'display';
if ( is_array( $size ) ) {
} elseif ( 'thumb' === $size || 'thumbnail' === $size ) {
$max_width = (int) get_option( 'thumbnail_size_w' );
$max_height = (int) get_option( 'thumbnail_size_h' );
// Last chance thumbnail size defaults.
if ( ! $max_width && ! $max_height ) {
} elseif ( 'medium' === $size ) {
$max_width = (int) get_option( 'medium_size_w' );
$max_height = (int) get_option( 'medium_size_h' );
} elseif ( 'medium_large' === $size ) {
$max_width = (int) get_option( 'medium_large_size_w' );
$max_height = (int) get_option( 'medium_large_size_h' );
if ( (int) $content_width > 0 ) {
$max_width = min( (int) $content_width, $max_width );
} elseif ( 'large' === $size ) {
* We're inserting a large size image into the editor. If it's a really
* big image we'll scale it down to fit reasonably within the editor
* itself, and within the theme's content width if it's known. The user
* can resize it in the editor if they wish.
$max_width = (int) get_option( 'large_size_w' );
$max_height = (int) get_option( 'large_size_h' );
if ( (int) $content_width > 0 ) {
$max_width = min( (int) $content_width, $max_width );
} elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ), true ) ) {
$max_width = (int) $_wp_additional_image_sizes[ $size ]['width'];
$max_height = (int) $_wp_additional_image_sizes[ $size ]['height'];
// Only in admin. Assume that theme authors know what they're doing.
if ( (int) $content_width > 0 && 'edit' === $context ) {
$max_width = min( (int) $content_width, $max_width );
} else { // $size === 'full' has no constraint.
* Filters the maximum image size dimensions for the editor.
* @param int[] $max_image_size {
* An array of width and height values.
* @type int $0 The maximum width in pixels.
* @type int $1 The maximum height in pixels.
* @param string|int[] $size Requested image size. Can be any registered image size name, or
* an array of width and height values in pixels (in that order).
* @param string $context The context the image is being resized for.
* Possible values are 'display' (like in a theme)
* or 'edit' (like inserting into an editor).
list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context );
return wp_constrain_dimensions( $width, $height, $max_width, $max_height );
* Retrieve width and height attributes using given width and height values.
* Both attributes are required in the sense that both parameters must have a
* value, but are optional in that if you set them to false or null, then they
* will not be added to the returned string.
* You can set the value using a string, but it will only take numeric values.
* If you wish to put 'px' after the numbers, then it will be stripped out of
* @param int|string $width Image width in pixels.
* @param int|string $height Image height in pixels.
* @return string HTML attributes for width and, or height.
function image_hwstring( $width, $height ) {
$out .= 'width="' . (int) $width . '" ';
$out .= 'height="' . (int) $height . '" ';
* Scale an image to fit a particular size (such as 'thumb' or 'medium').
* The URL might be the original image, or it might be a resized version. This
* function won't create a new resized copy, it will just return an already
* resized one if it exists.
* A plugin may use the {@see 'image_downsize'} filter to hook into and offer image
* resizing services for images. The hook must return an array with the same
* elements that are normally returned from the function.
* @param int $id Attachment ID for image.
* @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array
* of width and height values in pixels (in that order). Default 'medium'.
* Array of image data, or boolean false if no image is available.
* @type string $0 Image source URL.
* @type int $1 Image width in pixels.
* @type int $2 Image height in pixels.
* @type bool $3 Whether the image is a resized image.
function image_downsize( $id, $size = 'medium' ) {
$is_image = wp_attachment_is_image( $id );
* Filters whether to preempt the output of image_downsize().
* Returning a truthy value from the filter will effectively short-circuit
* down-sizing the image, returning that value instead.
* @param bool|array $downsize Whether to short-circuit the image downsize.
* @param int $id Attachment ID for image.
* @param string|int[] $size Requested image size. Can be any registered image size name, or
* an array of width and height values in pixels (in that order).
$out = apply_filters( 'image_downsize', false, $id, $size );
$img_url = wp_get_attachment_url( $id );
$meta = wp_get_attachment_metadata( $id );
$is_intermediate = false;
$img_url_basename = wp_basename( $img_url );
// If the file isn't an image, attempt to replace its URL with a rendered image from its meta.
// Otherwise, a non-image type could be returned.
if ( ! empty( $meta['sizes']['full'] ) ) {
$img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url );
$img_url_basename = $meta['sizes']['full']['file'];
$width = $meta['sizes']['full']['width'];
$height = $meta['sizes']['full']['height'];
// Try for a new style intermediate size.
$intermediate = image_get_intermediate_size( $id, $size );
$img_url = str_replace( $img_url_basename, $intermediate['file'], $img_url );
$width = $intermediate['width'];
$height = $intermediate['height'];
} elseif ( 'thumbnail' === $size ) {
// Fall back to the old thumbnail.
$thumb_file = wp_get_attachment_thumb_file( $id );
$info = wp_getimagesize( $thumb_file );
if ( $thumb_file && $info ) {
$img_url = str_replace( $img_url_basename, wp_basename( $thumb_file ), $img_url );
if ( ! $width && ! $height && isset( $meta['width'], $meta['height'] ) ) {
// Any other type: use the real image.
$height = $meta['height'];
// We have the actual image size, but might need to further constrain it if content_width is narrower.
list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size );
return array( $img_url, $width, $height, $is_intermediate );
* Register a new image size.
* @global array $_wp_additional_image_sizes Associative array of additional image sizes.
* @param string $name Image size identifier.
* @param int $width Optional. Image width in pixels. Default 0.
* @param int $height Optional. Image height in pixels. Default 0.
* @param bool|array $crop Optional. Image cropping behavior. If false, the image will be scaled (default),
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location.
* Array values must be in the format: array( x_crop_position, y_crop_position ) where:
* - x_crop_position accepts: 'left', 'center', or 'right'.
* - y_crop_position accepts: 'top', 'center', or 'bottom'.
function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
global $_wp_additional_image_sizes;
$_wp_additional_image_sizes[ $name ] = array(
'width' => absint( $width ),
'height' => absint( $height ),
* Check if an image size exists.
* @param string $name The image size to check.
* @return bool True if the image size exists, false if not.
function has_image_size( $name ) {
$sizes = wp_get_additional_image_sizes();
return isset( $sizes[ $name ] );
* Remove a new image size.
* @global array $_wp_additional_image_sizes
* @param string $name The image size to remove.
* @return bool True if the image size was successfully removed, false on failure.
function remove_image_size( $name ) {
global $_wp_additional_image_sizes;
if ( isset( $_wp_additional_image_sizes[ $name ] ) ) {
unset( $_wp_additional_image_sizes[ $name ] );
* Registers an image size for the post thumbnail.
* @see add_image_size() for details on cropping behavior.
* @param int $width Image width in pixels.
* @param int $height Image height in pixels.
* @param bool|array $crop Optional. Whether to crop images to specified width and height or resize.
* An array can specify positioning of the crop area. Default false.
function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
add_image_size( 'post-thumbnail', $width, $height, $crop );
* Gets an img tag for an image attachment, scaling it down if requested.
* The {@see 'get_image_tag_class'} filter allows for changing the class name for the
* image without having to use regular expressions on the HTML content. The
* parameters are: what WordPress will use for the class, the Attachment ID,
* image align value, and the size the image should be.
* The second filter, {@see 'get_image_tag'}, has the HTML content, which can then be
* further manipulated by a plugin to change all attribute values and even HTML
* @param int $id Attachment ID.
* @param string $alt Image description for the alt attribute.
* @param string $title Image description for the title attribute.
* @param string $align Part of the class name for aligning the image.
* @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of
* width and height values in pixels (in that order). Default 'medium'.
* @return string HTML IMG element for given image attachment
function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) {
list( $img_src, $width, $height ) = image_downsize( $id, $size );
$hwstring = image_hwstring( $width, $height );
$title = $title ? 'title="' . esc_attr( $title ) . '" ' : '';
$size_class = is_array( $size ) ? implode( 'x', $size ) : $size;
$class = 'align' . esc_attr( $align ) . ' size-' . esc_attr( $size_class ) . ' wp-image-' . $id;
* Filters the value of the attachment's image tag class attribute.
* @param string $class CSS class name or space-separated list of classes.
* @param int $id Attachment ID.
* @param string $align Part of the class name for aligning the image.
* @param string|int[] $size Requested image size. Can be any registered image size name, or
* an array of width and height values in pixels (in that order).
$class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
$html = '<img src="' . esc_attr( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
* Filters the HTML content for the image tag.
* @param string $html HTML content for the image.
* @param int $id Attachment ID.
* @param string $alt Image description for the alt attribute.
* @param string $title Image description for the title attribute.
* @param string $align Part of the class name for aligning the image.
* @param string|int[] $size Requested image size. Can be any registered image size name, or
* an array of width and height values in pixels (in that order).
return apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size );
* Calculates the new dimensions for a down-sampled image.
* If either width or height are empty, no constraint is applied on
* @param int $current_width Current width of the image.
* @param int $current_height Current height of the image.
* @param int $max_width Optional. Max width in pixels to constrain to. Default 0.
* @param int $max_height Optional. Max height in pixels to constrain to. Default 0.
* An array of width and height values.
* @type int $0 The width in pixels.
* @type int $1 The height in pixels.
function wp_constrain_dimensions( $current_width, $current_height, $max_width = 0, $max_height = 0 ) {
if ( ! $max_width && ! $max_height ) {
return array( $current_width, $current_height );
if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
$width_ratio = $max_width / $current_width;
if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
$height_ratio = $max_height / $current_height;
// Calculate the larger/smaller ratios.
$smaller_ratio = min( $width_ratio, $height_ratio );
$larger_ratio = max( $width_ratio, $height_ratio );
if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) {
// The larger ratio is too big. It would result in an overflow.
// The larger ratio fits, and is likely to be a more "snug" fit.
// Very small dimensions may result in 0, 1 should be the minimum.
$w = max( 1, (int) round( $current_width * $ratio ) );
$h = max( 1, (int) round( $current_height * $ratio ) );
* Sometimes, due to rounding, we'll end up with a result like this:
* 465x700 in a 177x177 box is 117x176... a pixel short.
* We also have issues with recursive calls resulting in an ever-changing result.
* Constraining to the result of a constraint should yield the original result.
* Thus we look for dimensions that are one pixel shy of the max value and bump them up.
// Note: $did_width means it is possible $smaller_ratio == $width_ratio.
if ( $did_width && $w === $max_width - 1 ) {
$w = $max_width; // Round it up.
// Note: $did_height means it is possible $smaller_ratio == $height_ratio.
if ( $did_height && $h === $max_height - 1 ) {
$h = $max_height; // Round it up.
* Filters dimensions to constrain down-sampled images to.
* @param int[] $dimensions {
* An array of width and height values.
* @type int $0 The width in pixels.
* @type int $1 The height in pixels.
* @param int $current_width The current width of the image.
* @param int $current_height The current height of the image.
* @param int $max_width The maximum width permitted.