函数文档

wp_generate_attachment_metadata()

💡 云策文档标注

概述

wp_generate_attachment_metadata() 是 WordPress 核心函数,用于生成附件元数据并为图像创建子尺寸。它处理图像、视频、音频和 PDF 文件,基于媒体设置生成缩略图和其他中间尺寸。

关键要点

  • 函数接受两个参数:$attachment_id(附件 ID)和 $file(服务器上的文件绝对路径,必须在上传目录中)。
  • 返回一个数组格式的元数据,包含宽度、高度、文件路径、尺寸信息(如缩略图、中等、大尺寸等)和图像元数据,适用于 wp_update_attachment_metadata()。
  • 支持多种 MIME 类型:图像(包括 HEIC)、视频、音频和 PDF,并针对非图像类型(如 PDF)生成回退尺寸。
  • 仅当中间尺寸小于原图大小时才生成子尺寸,且不会检查或删除之前创建的尺寸。
  • 通常与 wp_update_attachment_metadata() 结合使用,以更新附件元数据。
  • 在短代码等环境中使用时,需确保函数已定义,可通过 include 引入 wp-admin/includes/image.php。

代码示例

if ( ! function_exists( 'wp_crop_image' ) ) {
    include( ABSPATH . 'wp-admin/includes/image.php' );
}

注意事项

  • 文件路径必须使用绝对路径,而非 URI,且位于上传目录中。
  • 函数不会自动删除旧的中间尺寸,需手动管理。
  • 使用前确保环境支持相关函数,必要时引入依赖文件。

📄 原文内容

Generates attachment meta data and create image sub-sizes for images.

Parameters

$attachment_idintrequired
Attachment ID to process.
$filestringrequired
Filepath of the attached image.

Return

array Metadata for attachment.

More Information

This function generates metadata for an image attachment. It also creates a thumbnail and other intermediate sizes of the image attachment based on the sizes defined on the Settings_Media_Screen.

Parameter $file is  the location of the file on the server. Use absolute path and not the URI of the file. The file MUST be in the uploads directory. See wp_upload_dir().

This function returns array of attachment metadata in the format required by wp_update_attachment_metadata(). The elements returned in the array are:

["width"]
(string) Horizontal size of image attachment, in pixels.
["height"]
(string) Vertical size of image attachment, in pixels.
["file"]
(string) Path to image attachment, relative to the currently configured uploads directory.
["hwstring_small"]
(string) Height/width string for HTML img tag used to display the Small size of this image.
For example: height='96' width='126'
["sizes"]["thumbnail"]["file"]
(string) File name of Thumbnail-sized copy of image attachment.
["sizes"]["thumbnail"]["width"]
(string) Horizontal size of Thumbnail-sized copy of image attachment, in pixels.
["sizes"]["thumbnail"]["height"]
(string) Vertical size of Thumbnail-sized copy of image attachment, in pixels.
["sizes"]["medium"]
(array) Same three elements as ["sizes"]["thumbnail"] but for Medium-sized copy of image attachment.
["sizes"]["large"]
(array) Same three elements as ["sizes"]["thumbnail"] but for Large-sized copy of image attachment.
["sizes"]["post-thumbnail"]
(array) Same three elements as ["sizes"]["thumbnail"] but for Post Thumbnail-sized copy of image attachment.
["sizes"]["large-feature"]
(array) Same three elements as ["sizes"]["thumbnail"] but for Large Feature-sized copy of image attachment.
["sizes"]["small-feature"]
(array) Same three elements as ["sizes"]["thumbnail"] but for Small Feature-sized copy of image attachment.
["image_meta"]
(array) Image attachment Metadata returned by wp_read_image_metadata()

This function can be used to regenerate thumbnail and intermediate sizes of the image after changes have been made on the Settings_Media_Screen but it does not check or delete intermediate sizes it previously created for the same image.

Thumbnail and intermediate sizes of the image, and [“sizes”] elements in the array returned by this function, are only generated when the intermediate size is smaller than the size of the image.

The function should be used in conjunction with wp_update_attachment_metadata().

If this function is undefined in the environment where it is to be used, such as within a Shortcode, use the include function:

if ( ! function_exists( 'wp_crop_image' ) ) {
include( ABSPATH . 'wp-admin/includes/image.php' );
}

Source

function wp_generate_attachment_metadata( $attachment_id, $file ) {
	$attachment = get_post( $attachment_id );

	$metadata  = array();
	$support   = false;
	$mime_type = get_post_mime_type( $attachment );

	if ( 'image/heic' === $mime_type || ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) ) {
		// Make thumbnails and other intermediate sizes.
		$metadata = wp_create_image_subsizes( $file, $attachment_id );
	} elseif ( wp_attachment_is( 'video', $attachment ) ) {
		$metadata = wp_read_video_metadata( $file );
		$support  = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
	} elseif ( wp_attachment_is( 'audio', $attachment ) ) {
		$metadata = wp_read_audio_metadata( $file );
		$support  = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
	}

	/*
	 * wp_read_video_metadata() and wp_read_audio_metadata() return `false`
	 * if the attachment does not exist in the local filesystem,
	 * so make sure to convert the value to an array.
	 */
	if ( ! is_array( $metadata ) ) {
		$metadata = array();
	}

	if ( $support && ! empty( $metadata['image']['data'] ) ) {
		// Check for existing cover.
		$hash   = md5( $metadata['image']['data'] );
		$posts  = get_posts(
			array(
				'fields'         => 'ids',
				'post_type'      => 'attachment',
				'post_mime_type' => $metadata['image']['mime'],
				'post_status'    => 'inherit',
				'posts_per_page' => 1,
				'meta_key'       => '_cover_hash',
				'meta_value'     => $hash,
			)
		);
		$exists = reset( $posts );

		if ( ! empty( $exists ) ) {
			update_post_meta( $attachment_id, '_thumbnail_id', $exists );
		} else {
			$ext = '.jpg';
			switch ( $metadata['image']['mime'] ) {
				case 'image/gif':
					$ext = '.gif';
					break;
				case 'image/png':
					$ext = '.png';
					break;
				case 'image/webp':
					$ext = '.webp';
					break;
			}
			$basename = str_replace( '.', '-', wp_basename( $file ) ) . '-image' . $ext;
			$uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
			if ( false === $uploaded['error'] ) {
				$image_attachment = array(
					'post_mime_type' => $metadata['image']['mime'],
					'post_type'      => 'attachment',
					'post_content'   => '',
				);
				/**
				 * Filters the parameters for the attachment thumbnail creation.
				 *
				 * @since 3.9.0
				 *
				 * @param array $image_attachment An array of parameters to create the thumbnail.
				 * @param array $metadata         Current attachment metadata.
				 * @param array $uploaded         {
				 *     Information about the newly-uploaded file.
				 *
				 *     @type string $file  Filename of the newly-uploaded file.
				 *     @type string $url   URL of the uploaded file.
				 *     @type string $type  File type.
				 * }
				 */
				$image_attachment = apply_filters( 'attachment_thumbnail_args', $image_attachment, $metadata, $uploaded );

				$sub_attachment_id = wp_insert_attachment( $image_attachment, $uploaded['file'] );
				add_post_meta( $sub_attachment_id, '_cover_hash', $hash );
				$attach_data = wp_generate_attachment_metadata( $sub_attachment_id, $uploaded['file'] );
				wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
				update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
			}
		}
	} elseif ( 'application/pdf' === $mime_type ) {
		// Try to create image thumbnails for PDFs.

		$fallback_sizes = array(
			'thumbnail',
			'medium',
			'large',
		);

		/**
		 * Filters the image sizes generated for non-image mime types.
		 *
		 * @since 4.7.0
		 *
		 * @param string[] $fallback_sizes An array of image size names.
		 * @param array    $metadata       Current attachment metadata.
		 */
		$fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );

		$registered_sizes = wp_get_registered_image_subsizes();
		$merged_sizes     = array_intersect_key( $registered_sizes, array_flip( $fallback_sizes ) );

		// Force thumbnails to be soft crops.
		if ( isset( $merged_sizes['thumbnail'] ) && is_array( $merged_sizes['thumbnail'] ) ) {
			$merged_sizes['thumbnail']['crop'] = false;
		}

		// Only load PDFs in an image editor if we're processing sizes.
		if ( ! empty( $merged_sizes ) ) {
			$editor = wp_get_image_editor( $file );

			if ( ! is_wp_error( $editor ) ) { // No support for this type of file.
				/*
				 * PDFs may have the same file filename as JPEGs.
				 * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
				 */
				$dirname      = dirname( $file ) . '/';
				$ext          = '.' . pathinfo( $file, PATHINFO_EXTENSION );
				$preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );

				$uploaded = $editor->save( $preview_file, 'image/jpeg' );
				unset( $editor );

				// Resize based on the full size image, rather than the source.
				if ( ! is_wp_error( $uploaded ) ) {
					$image_file = $uploaded['path'];
					unset( $uploaded['path'] );

					$metadata['sizes'] = array(
						'full' => $uploaded,
					);

					// Save the meta data before any image post-processing errors could happen.
					wp_update_attachment_metadata( $attachment_id, $metadata );

					// Create sub-sizes saving the image meta after each.
					$metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id );
				}
			}
		}
	}

	// Remove the blob of binary data from the array.
	unset( $metadata['image']['data'] );

	// Capture file size for cases where it has not been captured yet, such as PDFs.
	if ( ! isset( $metadata['filesize'] ) && file_exists( $file ) ) {
		$metadata['filesize'] = wp_filesize( $file );
	}

	/**
	 * Filters the generated attachment meta data.
	 *
	 * @since 2.1.0
	 * @since 5.3.0 The `$context` parameter was added.
	 *
	 * @param array  $metadata      An array of attachment meta data.
	 * @param int    $attachment_id Current attachment ID.
	 * @param string $context       Additional context. Can be 'create' when metadata was initially created for new attachment
	 *                              or 'update' when the metadata was updated.
	 */
	return apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id, 'create' );
}

Hooks

apply_filters( ‘attachment_thumbnail_args’, array $image_attachment, array $metadata, array $uploaded )

Filters the parameters for the attachment thumbnail creation.

apply_filters( ‘fallback_intermediate_image_sizes’, string[] $fallback_sizes, array $metadata )

Filters the image sizes generated for non-image mime types.

apply_filters( ‘wp_generate_attachment_metadata’, array $metadata, int $attachment_id, string $context )

Filters the generated attachment meta data.

Changelog

Version Description
6.7.0 The 'image/heic' mime type is supported.
6.0.0 The $filesize value was added to the returned array.
2.1.0 Introduced.

User Contributed Notes