函数文档

_wp_make_subsizes()

💡 云策文档标注

概述

_wp_make_subsizes() 是 WordPress 中用于创建图像子尺寸的低级函数,主要用于更新图像元数据并处理生成过程中的错误。它通过检查现有尺寸、排序优先级、调用图像编辑器来生成新尺寸,并返回更新后的元数据数组。

关键要点

  • 函数用于创建图像子尺寸,更新图像元数据,并存储错误信息在返回的数组中。
  • 参数包括 $new_sizes(定义要创建的尺寸数组)、$file(图像文件路径)、$image_meta(附件元数据数组)和 $attachment_id(附件 ID)。
  • 函数会检查并跳过已存在的尺寸,按优先级(如 medium、large)排序新尺寸,使用 wp_get_image_editor 处理图像。
  • 支持通过 make_subsize 方法或回退到 multi_resize 方法生成尺寸,并自动更新附件元数据。
  • 这是一个内部函数,不建议在主题或插件代码中直接使用,但可用于按需创建特定图像尺寸以优化存储。

代码示例

$attachment_id = 12345;
$needed_sizes = array(
    'some_size' => array(
        'width' => 420,
        'height' => 420,
        'crop' => false
    ),
    'some_size_2' => array(
        'width' => 69,
        'height' => 69,
        'crop' => true
    )
);
require_once ABSPATH . 'wp-admin/includes/image.php';
_wp_make_subsizes( $needed_sizes, wp_get_original_image_path( $attachment_id ), wp_get_attachment_metadata( $attachment_id ), $attachment_id );

注意事项

  • 函数是内部函数,主要用于 WordPress 核心功能,如 wp_update_image_subsizes() 和 wp_create_image_subsizes()。
  • 使用时需确保参数正确,避免重复创建尺寸或处理错误图像文件。
  • 在插件或主题中应谨慎使用,优先考虑标准方法如 add_image_size,仅在特定优化场景下使用此函数。

📄 原文内容

Low-level function to create image sub-sizes.

Description

Updates the image meta after each sub-size is created.
Errors are stored in the returned image metadata array.

Parameters

$new_sizesarrayrequired
Array defining what sizes to create.
$filestringrequired
Full path to the image file.
$image_metaarrayrequired
The attachment meta data array.
$attachment_idintrequired
Attachment ID to process.

Return

array The attachment meta data with updated sizes array. Includes an array of errors encountered while resizing.

Source

function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) {
	if ( empty( $image_meta ) || ! is_array( $image_meta ) ) {
		// Not an image attachment.
		return array();
	}

	// Check if any of the new sizes already exist.
	if ( isset( $image_meta['sizes'] ) && is_array( $image_meta['sizes'] ) ) {
		foreach ( $image_meta['sizes'] as $size_name => $size_meta ) {
			/*
			 * Only checks "size name" so we don't override existing images even if the dimensions
			 * don't match the currently defined size with the same name.
			 * To change the behavior, unset changed/mismatched sizes in the `sizes` array in image meta.
			 */
			if ( array_key_exists( $size_name, $new_sizes ) ) {
				unset( $new_sizes[ $size_name ] );
			}
		}
	} else {
		$image_meta['sizes'] = array();
	}

	if ( empty( $new_sizes ) ) {
		// Nothing to do...
		return $image_meta;
	}

	/*
	 * Sort the image sub-sizes in order of priority when creating them.
	 * This ensures there is an appropriate sub-size the user can access immediately
	 * even when there was an error and not all sub-sizes were created.
	 */
	$priority = array(
		'medium'       => null,
		'large'        => null,
		'thumbnail'    => null,
		'medium_large' => null,
	);

	$new_sizes = array_filter( array_merge( $priority, $new_sizes ) );

	$editor = wp_get_image_editor( $file );

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

	// If stored EXIF data exists, rotate the source image before creating sub-sizes.
	if ( ! empty( $image_meta['image_meta'] ) ) {
		$rotated = $editor->maybe_exif_rotate();

		if ( is_wp_error( $rotated ) ) {
			// TODO: Log errors.
		}
	}

	if ( method_exists( $editor, 'make_subsize' ) ) {
		foreach ( $new_sizes as $new_size_name => $new_size_data ) {
			$new_size_meta = $editor->make_subsize( $new_size_data );

			if ( is_wp_error( $new_size_meta ) ) {
				// TODO: Log errors.
			} else {
				// Save the size meta value.
				$image_meta['sizes'][ $new_size_name ] = $new_size_meta;
				wp_update_attachment_metadata( $attachment_id, $image_meta );
			}
		}
	} else {
		// Fall back to `$editor->multi_resize()`.
		$created_sizes = $editor->multi_resize( $new_sizes );

		if ( ! empty( $created_sizes ) ) {
			$image_meta['sizes'] = array_merge( $image_meta['sizes'], $created_sizes );
			wp_update_attachment_metadata( $attachment_id, $image_meta );
		}
	}

	return $image_meta;
}

Changelog

Version Description
5.3.0 Introduced.

User Contributed Notes

  1. Skip to note 2 content

    I know this is an internal wp function not meant to be used in theme or plugin code, however using it is the only way I found to solve a problem: to programmatically create some additional image sizes when needed.

    For example I have a plugin that when we upload some image to it, it needs to have that image in 3 specific sizes. This plugin solves that by registering those sizes via add_image_size. But this way those sizes (and files) are created for all images uploaded to website, but only some of them will be used for that plugin. That is bad if multiple plugins do that and if you have over 25k uploads on a website – it reaches tens of gigs in disk usage with all those unnecessary thumbnails for every upload.

    So my solution to that is to remove_image_size for those plugin’s sizes, and to create needed sizes only for images actually used by that plugin based on some hook like so:

    $attachment_id = 12345;
    $needed_sizes = array(
    	'some_size' => array(
    		'width' => 420,
    		'height' => 420,
    		'crop' => false
    	),
    	'some_size_2' => array(
    		'width' => 69,
    		'height' => 69,
    		'crop' => true
    	)
    );
    require_once ABSPATH . 'wp-admin/includes/image.php';
    _wp_make_subsizes( $needed_sizes, wp_get_original_image_path( $attachment_id ), wp_get_attachment_metadata( $attachment_id ), $attachment_id );