函数文档

wp_create_image_subsizes()

💡 云策文档标注

概述

wp_create_image_subsizes() 函数用于在图片上传后创建子尺寸,更新图片元数据中的 sizes 数组。它处理大图缩放、格式转换和 EXIF 旋转,并调用相关函数生成子尺寸。

关键要点

  • 函数在图片上传后调用,创建子尺寸并更新元数据,返回图片附件元数据数组
  • 参数包括图片文件路径($file,字符串,必需)和附件 ID($attachment_id,整数,必需)
  • 内部处理包括:检查图片有效性、获取图片尺寸、读取 EXIF/IPTC 元数据、应用 big_image_size_threshold 过滤器进行大图缩放、处理格式转换和 EXIF 旋转
  • 使用 wp_update_attachment_metadata() 保存初始元数据,并通过 intermediate_image_sizes_advanced 过滤器调整子尺寸生成
  • 最终调用 _wp_make_subsizes() 创建子尺寸并返回更新后的元数据

代码示例

function wp_create_image_subsizes( $file, $attachment_id ) {
    $imagesize = wp_getimagesize( $file );

    if ( empty( $imagesize ) ) {
        // File is not an image.
        return array();
    }

    // Default image meta.
    $image_meta = array(
        'width'    => $imagesize[0],
        'height'   => $imagesize[1],
        'file'     => _wp_relative_upload_path( $file ),
        'filesize' => wp_filesize( $file ),
        'sizes'    => array(),
    );

    // Fetch additional metadata from EXIF/IPTC.
    $exif_meta = wp_read_image_metadata( $file );

    if ( $exif_meta ) {
        $image_meta['image_meta'] = $exif_meta;
    }

    $threshold = (int) apply_filters( 'big_image_size_threshold', 2560, $imagesize, $file, $attachment_id );

    // ... 后续处理缩放、转换、旋转等逻辑

    wp_update_attachment_metadata( $attachment_id, $image_meta );

    $new_sizes = wp_get_registered_image_subsizes();
    $new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );

    return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id );
}

注意事项

  • 函数返回数组类型的图片附件元数据,若文件不是图片则返回空数组
  • 错误处理通过 is_wp_error() 检查,但当前版本中错误仅记录 TODO 注释,未实际记录
  • 依赖多个 WordPress 核心函数,如 wp_get_image_editor()、wp_update_attachment_metadata() 等,需确保环境支持
  • 自 WordPress 5.3.0 版本引入,主要用于内部图片处理流程

📄 原文内容

Creates image sub-sizes, adds the new data to the image meta sizes array, and updates the image metadata.

Description

Intended for use after an image is uploaded. Saves/updates the image metadata after each sub-size is created. If there was an error, it is added to the returned image metadata array.

Parameters

$filestringrequired
Full path to the image file.
$attachment_idintrequired
Attachment ID to process.

Return

array The image attachment meta data.

Source

function wp_create_image_subsizes( $file, $attachment_id ) {
	$imagesize = wp_getimagesize( $file );

	if ( empty( $imagesize ) ) {
		// File is not an image.
		return array();
	}

	// Default image meta.
	$image_meta = array(
		'width'    => $imagesize[0],
		'height'   => $imagesize[1],
		'file'     => _wp_relative_upload_path( $file ),
		'filesize' => wp_filesize( $file ),
		'sizes'    => array(),
	);

	// Fetch additional metadata from EXIF/IPTC.
	$exif_meta = wp_read_image_metadata( $file );

	if ( $exif_meta ) {
		$image_meta['image_meta'] = $exif_meta;
	}

	/**
	 * Filters the "BIG image" threshold value.
	 *
	 * If the original image width or height is above the threshold, it will be scaled down. The threshold is
	 * used as max width and max height. The scaled down image will be used as the largest available size, including
	 * the `_wp_attached_file` post meta value.
	 *
	 * Returning `false` from the filter callback will disable the scaling.
	 *
	 * @since 5.3.0
	 *
	 * @param int    $threshold     The threshold value in pixels. Default 2560.
	 * @param array  $imagesize     {
	 *     Indexed array of the image width and height in pixels.
	 *
	 *     @type int $0 The image width.
	 *     @type int $1 The image height.
	 * }
	 * @param string $file          Full path to the uploaded image file.
	 * @param int    $attachment_id Attachment post ID.
	 */
	$threshold = (int) apply_filters( 'big_image_size_threshold', 2560, $imagesize, $file, $attachment_id );

	/*
	 * If the original image's dimensions are over the threshold,
	 * scale the image and use it as the "full" size.
	 */
	$scale_down = false;
	$convert    = false;

	if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) {
		// The image will be converted if needed on saving.
		$scale_down = true;
	} else {
		// The image may need to be converted regardless of its dimensions.
		$output_format = wp_get_image_editor_output_format( $file, $imagesize['mime'] );

		if (
			is_array( $output_format ) &&
			array_key_exists( $imagesize['mime'], $output_format ) &&
			$output_format[ $imagesize['mime'] ] !== $imagesize['mime']
		) {
			$convert = true;
		}
	}

	if ( $scale_down || $convert ) {
		$editor = wp_get_image_editor( $file );

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

		if ( $scale_down ) {
			// Resize the image. This will also convet it if needed.
			$resized = $editor->resize( $threshold, $threshold );
		} elseif ( $convert ) {
			// The image will be converted (if possible) when saved.
			$resized = true;
		}

		$rotated = null;

		// If there is EXIF data, rotate according to EXIF Orientation.
		if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) {
			$resized = $editor->maybe_exif_rotate();
			$rotated = $resized; // bool true or WP_Error
		}

		if ( ! is_wp_error( $resized ) ) {
			/*
			 * Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
			 * This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
			 */
			if ( $scale_down ) {
				$saved = $editor->save( $editor->generate_filename( 'scaled' ) );
			} elseif ( $convert ) {
				// Pass an empty string to avoid adding a suffix to converted file names.
				$saved = $editor->save( $editor->generate_filename( '' ) );
			} else {
				$saved = $editor->save();
			}

			if ( ! is_wp_error( $saved ) ) {
				$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );

				// If the image was rotated update the stored EXIF data.
				if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
					$image_meta['image_meta']['orientation'] = 1;
				}
			} else {
				// TODO: Log errors.
			}
		} else {
			// TODO: Log errors.
		}
	} elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) {
		// Rotate the whole original image if there is EXIF data and "orientation" is not 1.
		$editor = wp_get_image_editor( $file );

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

		// Rotate the image.
		$rotated = $editor->maybe_exif_rotate();

		if ( true === $rotated ) {
			// Append `-rotated` to the image file name.
			$saved = $editor->save( $editor->generate_filename( 'rotated' ) );

			if ( ! is_wp_error( $saved ) ) {
				$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );

				// Update the stored EXIF data.
				if ( ! empty( $image_meta['image_meta']['orientation'] ) ) {
					$image_meta['image_meta']['orientation'] = 1;
				}
			} else {
				// TODO: Log errors.
			}
		}
	}

	/*
	 * Initial save of the new metadata.
	 * At this point the file was uploaded and moved to the uploads directory
	 * but the image sub-sizes haven't been created yet and the `sizes` array is empty.
	 */
	wp_update_attachment_metadata( $attachment_id, $image_meta );

	$new_sizes = wp_get_registered_image_subsizes();

	/**
	 * Filters the image sizes automatically generated when uploading an image.
	 *
	 * @since 2.9.0
	 * @since 4.4.0 Added the `$image_meta` argument.
	 * @since 5.3.0 Added the `$attachment_id` argument.
	 *
	 * @param array $new_sizes     Associative array of image sizes to be created.
	 * @param array $image_meta    The image meta data: width, height, file, sizes, etc.
	 * @param int   $attachment_id The attachment post ID for the image.
	 */
	$new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );

	return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id );
}

Hooks

apply_filters( ‘big_image_size_threshold’, int $threshold, array $imagesize, string $file, int $attachment_id )

Filters the “BIG image” threshold value.

apply_filters( ‘intermediate_image_sizes_advanced’, array $new_sizes, array $image_meta, int $attachment_id )

Filters the image sizes automatically generated when uploading an image.

Changelog

Version Description
5.3.0 Introduced.