wp_generate_attachment_metadata()WP 2.1.0

Generates metadata for the image attachment and creates intermediate copies of the image - thumbnails of all registered sizes.

Intermediate sizes are specified in "Media Settings" (thumbnail, medium, large), and they can also be created by the function add_image_size() in the theme or plugin.

The function does not update the attachment metadata, but only creates them and all the necessary image sizes. Usually, after the function runs, you need to update the metadata using wp_update_attachment_metadata().

The function updates the meta-field of the post _thumbnail_id associated with the post's thumbnail.

This function can be used to recreate the thumbnail of the image attachment and all its intermediate sizes after the sizes have been changed in "Media Settings". However, this function does not delete already created intermediate sizes, but creates new ones in addition to the existing ones.

The thumbnail and intermediate sizes of the image, and the array element ["sizes"] are returned by the function only when the created size is smaller than the original size of the image; in other cases, the intermediate size is simply not created.

The function is not defined on the front-end, so to use it, for example, in a shortcode, you need to include it by adding the following line to the code:

require ABSPATH . 'wp-admin/includes/image.php';

Returns

Array. Attachment metadata.

Usage

wp_generate_attachment_metadata( $attachment_id, $file );
$attachment_id(number) (required)
ID of the image attachment whose metadata needs to be retrieved.
$file(string) (required)
Full path to the original image attachment.

Examples

0

#1 Demo of work

Let's say we have an attachment with ID 75 and the picture has already been uploaded and is in the uploads folder. Now let's create all its intermediate sizes:

// wp_generate_attachment_metadata() depends on this file.
require_once ABSPATH . 'wp-admin/includes/image.php';

$attach_id = 75;
$file = 'var/www/example.com/wp-content/uploads/2016/06/wordpress1.jpg';

$metadata = wp_generate_attachment_metadata( $attach_id, $file );
wp_update_attachment_metadata( $attach_id, $metadata );

$metadata will contain such an array:

Array
(
	[width] => 574
	[height] => 159
	[file] => 2016/06/wordpress1.jpg
	[sizes] => Array
		(
			[thumbnail] => Array
				(
					[file] => wordpress1-80x80.jpg
					[width] => 80
					[height] => 80
					[mime-type] => image/jpeg
				)

			[medium] => Array
				(
					[file] => wordpress1-120x33.jpg
					[width] => 120
					[height] => 33
					[mime-type] => image/jpeg
				)

		)

	[image_meta] => Array
		(
			[aperture] => 0
			[credit] => 
			[camera] => 
			 => 
			[created_timestamp] => 0
			[copyright] => 
			[focal_length] => 0
			[iso] => 0
			[shutter_speed] => 0
			[title] => 
			[orientation] => 0
			[keywords] => Array
				(
				)

		)

)
0

#2 Add already downloaded file to WP Media directory and to DB as attachment

Working example, shows how you can upload a picture to the uploads folder, attach it to the post 37 and create a thumbnail and all the intermediate dimensions of that picture.

// the file must be in the WP uploads (media) directory.
$filename = '/path/to/uploads/2013/03/filname.jpg';

// the ID of the post to which we are attaching the attachment.
$parent_post_id = 37;

// Check the post type that we will use in the 'post_mime_type' field.
$filetype = wp_check_filetype( basename( $filename ), null );

// Get the path to the download directory.
$wp_upload_dir = wp_upload_dir();

// Prepare the array with the necessary data for the nesting.
$attachment = array(
	'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ), 
	'post_mime_type' => $filetype['type'],
	'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
	'post_content'   => '',
	'post_status'    => 'inherit'
);

// Insert the post into the database.
$attach_id = wp_insert_attachment( $attachment, $filename, $parent_post_id );

// Connect the desired file, if it is not already connected
// wp_generate_attachment_metadata() depends on this file.
require_once ABSPATH . 'wp-admin/includes/image.php';

// Create metadata for the attachment and update the post in the database.
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );

Changelog

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

wp_generate_attachment_metadata() code WP 7.0

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