image_resize_dimensions()WP 2.5.0

Calculates dimensions and coordinates to resize an image so that it fits within a given width and height.

Used when creating smaller copies of images. The function computes which part of the source image to take and to what size it should be reduced or cropped.

If cropping is disabled, the image is scaled preserving proportions. If cropping is enabled, the image is fit to the specified size and the excess part is cut off.

The function does not change the image file by itself. It only calculates the coordinates and sizes that can then be used when resizing the image.

If the new size is larger than the source image, the function will usually return false to avoid creating an enlarged copy.

Returns

Array|false.

  • array — an array with sizes and coordinates in a format suitable for imagecopyresampled(): [dst_x, dst_y, src_x, src_y, dst_w, dst_h, src_w, src_h].
  • false — if the source dimensions are incorrect, no new size specified, the new size is larger than the source, or the new size is practically identical to the original.

Usage

image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop );
$orig_w(int) (required)
The width of the source image in pixels.
$orig_h(int) (required)
The height of the source image in pixels.
$dest_w(int) (required)
The new width of the image in pixels. You can pass 0 if the size should be calculated from the height.
$dest_h(int) (required)
The new height of the image in pixels. You can pass 0 if the size should be calculated from the width.
$crop(bool|array)

Determines whether the image should be cropped.

If false, the image is scaled preserving proportions.

If true, the image is cropped from the center.

If an array is passed, you can specify the crop position:
the first value for the X axis (left, center, right),
the second — for the Y axis (top, center, bottom).

Default: false

Examples

0

#1 Getting dimensions for standard scaling

The image will be scaled down to fit within a 300x300 area without cropping.

$dimensions = image_resize_dimensions( 1200, 800, 300, 300 );

if ( false !== $dimensions ) {
	list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dimensions;

	echo 'New size: ' . $dst_w . 'x' . $dst_h;
}
0

#2 Getting dimensions for center crop

The image will be cropped and fitted to 300x300.

$dimensions = image_resize_dimensions( 1200, 800, 300, 300, true );

if ( false !== $dimensions ) {
	list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dimensions;

	echo 'Cropping starts at point: ' . $src_x . 'x' . $src_y;
}
0

#3 Cropping an image from the top-left corner

You can specify where to take the image area for cropping from.

$dimensions = image_resize_dimensions( 1200, 800, 300, 300, [ 'left', 'top' ] );

if ( false !== $dimensions ) {
	list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dimensions;

	echo 'Source: ' . $src_x . 'x' . $src_y;
}
0

#4 Changing the result via a filter

The image_resize_dimensions filter allows you to completely replace the standard size calculation.

add_filter( 'image_resize_dimensions', 'my_image_resize_dimensions', 10, 6 );

function my_image_resize_dimensions( $output, $orig_w, $orig_h, $dest_w, $dest_h, $crop ) {
	if ( 300 === $dest_w && 300 === $dest_h ) {
		return [ 0, 0, 0, 0, 300, 300, min( 300, $orig_w ), min( 300, $orig_h ) ];
	}

	return $output;
}

Changelog

Since 2.5.0 Introduced.

image_resize_dimensions() code WP 7.0

function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) {

	if ( $orig_w <= 0 || $orig_h <= 0 ) {
		return false;
	}
	// At least one of $dest_w or $dest_h must be specific.
	if ( $dest_w <= 0 && $dest_h <= 0 ) {
		return false;
	}

	/**
	 * Filters whether to preempt calculating the image resize dimensions.
	 *
	 * Returning a non-null value from the filter will effectively short-circuit
	 * image_resize_dimensions(), returning that value instead.
	 *
	 * @since 3.4.0
	 *
	 * @param null|mixed $null   Whether to preempt output of the resize dimensions.
	 * @param int        $orig_w Original width in pixels.
	 * @param int        $orig_h Original height in pixels.
	 * @param int        $dest_w New width in pixels.
	 * @param int        $dest_h New height in pixels.
	 * @param bool|array $crop   Whether to crop image to specified width and height or resize.
	 *                           An array can specify positioning of the crop area. Default false.
	 */
	$output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop );

	if ( null !== $output ) {
		return $output;
	}

	// Stop if the destination size is larger than the original image dimensions.
	if ( empty( $dest_h ) ) {
		if ( $orig_w < $dest_w ) {
			return false;
		}
	} elseif ( empty( $dest_w ) ) {
		if ( $orig_h < $dest_h ) {
			return false;
		}
	} else {
		if ( $orig_w < $dest_w && $orig_h < $dest_h ) {
			return false;
		}
	}

	if ( $crop ) {
		/*
		 * Crop the largest possible portion of the original image that we can size to $dest_w x $dest_h.
		 * Note that the requested crop dimensions are used as a maximum bounding box for the original image.
		 * If the original image's width or height is less than the requested width or height
		 * only the greater one will be cropped.
		 * For example when the original image is 600x300, and the requested crop dimensions are 400x400,
		 * the resulting image will be 400x300.
		 */
		$aspect_ratio = $orig_w / $orig_h;
		$new_w        = min( $dest_w, $orig_w );
		$new_h        = min( $dest_h, $orig_h );

		if ( ! $new_w ) {
			$new_w = (int) round( $new_h * $aspect_ratio );
		}

		if ( ! $new_h ) {
			$new_h = (int) round( $new_w / $aspect_ratio );
		}

		$size_ratio = max( $new_w / $orig_w, $new_h / $orig_h );

		$crop_w = round( $new_w / $size_ratio );
		$crop_h = round( $new_h / $size_ratio );

		if ( ! is_array( $crop ) || count( $crop ) !== 2 ) {
			$crop = array( 'center', 'center' );
		}

		list( $x, $y ) = $crop;

		if ( 'left' === $x ) {
			$s_x = 0;
		} elseif ( 'right' === $x ) {
			$s_x = $orig_w - $crop_w;
		} else {
			$s_x = floor( ( $orig_w - $crop_w ) / 2 );
		}

		if ( 'top' === $y ) {
			$s_y = 0;
		} elseif ( 'bottom' === $y ) {
			$s_y = $orig_h - $crop_h;
		} else {
			$s_y = floor( ( $orig_h - $crop_h ) / 2 );
		}
	} else {
		// Resize using $dest_w x $dest_h as a maximum bounding box.
		$crop_w = $orig_w;
		$crop_h = $orig_h;

		$s_x = 0;
		$s_y = 0;

		list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h );
	}

	if ( wp_fuzzy_number_match( $new_w, $orig_w ) && wp_fuzzy_number_match( $new_h, $orig_h ) ) {
		// The new size has virtually the same dimensions as the original image.

		/**
		 * Filters whether to proceed with making an image sub-size with identical dimensions
		 * with the original/source image. Differences of 1px may be due to rounding and are ignored.
		 *
		 * @since 5.3.0
		 *
		 * @param bool $proceed The filtered value.
		 * @param int  $orig_w  Original image width.
		 * @param int  $orig_h  Original image height.
		 */
		$proceed = (bool) apply_filters( 'wp_image_resize_identical_dimensions', false, $orig_w, $orig_h );

		if ( ! $proceed ) {
			return false;
		}
	}

	/*
	 * The return array matches the parameters to imagecopyresampled().
	 * int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
	 */
	return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );
}