函数文档

image_resize_dimensions()

💡 云策文档标注

概述

image_resize_dimensions() 函数用于计算图像调整尺寸后的维度,供 WP_Image_Editor 使用。它根据原始尺寸、目标尺寸和裁剪行为,返回适合 imagecopyresampled() 的参数数组。

关键要点

  • 函数计算图像调整尺寸后的宽度、高度和坐标,以适应指定尺寸。
  • 参数包括原始宽度、原始高度、目标宽度、目标高度和可选的裁剪行为(布尔值或数组)。
  • 裁剪行为可设置为 false(缩放)、true(居中裁剪)或数组(指定裁剪位置)。
  • 返回值为数组(匹配 imagecopyresampled() 参数)或 false(失败时)。
  • 提供两个过滤器:'image_resize_dimensions' 和 'wp_image_resize_identical_dimensions',用于自定义维度计算逻辑。
  • 相关函数包括 wp_fuzzy_number_match()、wp_constrain_dimensions() 和 apply_filters()。
  • 自 WordPress 2.5.0 版本引入。

📄 原文内容

Retrieves calculated resize dimensions for use in WP_Image_Editor.

Description

Calculates dimensions and coordinates for a resized image that fits within a specified width and height.

Parameters

$orig_wintrequired
Original width in pixels.
$orig_hintrequired
Original height in pixels.
$dest_wintrequired
New width in pixels.
$dest_hintrequired
New height in pixels.
$cropbool|arrayoptional
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:

  • 0 string
    The x crop position. Accepts 'left', 'center', or 'right'.
  • 1 string
    The y crop position. Accepts 'top', 'center', or 'bottom'.

Default:false

Return

array|false Returned array matches parameters for imagecopyresampled(). False on failure.

Source

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 );
}

Hooks

apply_filters( ‘image_resize_dimensions’, null|mixed $null, int $orig_w, int $orig_h, int $dest_w, int $dest_h, bool|array $crop )

Filters whether to preempt calculating the image resize dimensions.

apply_filters( ‘wp_image_resize_identical_dimensions’, bool $proceed, int $orig_w, int $orig_h )

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.

Changelog

Version Description
2.5.0 Introduced.