WordPress Version: 6.3
/**
* Creates image sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata.
*
* 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.
*
* @since 5.3.0
*
* @param string $file Full path to the image file.
* @param int $attachment_id Attachment ID to process.
* @return array The image attachment meta data.
*/
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;
}
// Do not scale (large) PNG images. May result in sub-sizes that have greater file size than the original. See #48736.
if ('image/png' !== $imagesize['mime']) {
/**
* 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.
*/
if ($threshold && ($image_meta['width'] > $threshold || $image_meta['height'] > $threshold)) {
$editor = wp_get_image_editor($file);
if (is_wp_error($editor)) {
// This image cannot be edited.
return $image_meta;
}
// Resize the image.
$resized = $editor->resize($threshold, $threshold);
$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;
}
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).
*/
$saved = $editor->save($editor->generate_filename('scaled'));
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);
}