wp_generate_attachment_metadata( int $attachment_id, string $file ): array

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

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

User Contributed Notes

  1. Skip to note 2 content

    Example
    To generate attachment metadata for attachment with parent post ID 37:

    <?php
    $attach_id = wp_insert_attachment( $attachment, $filename, 37 );
    $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
    wp_update_attachment_metadata( $attach_id,  $attach_data );
    ?>

You must log in before being able to contribute a note or feedback.