Make WordPress Core


Ignore:
Timestamp:
02/20/2025 06:44:02 AM (19 months ago)
Author:
adamsilverstein
Message:

Media: fix full size image generation for PNG uploads.

Remove a limitation that prevented PNG uploads from generating the full sized image. Fixes a bug where using the image_editor_output_format filter would not generate full sized images as expected. The removed code was present to prevent overly large PNG image output, however this issue was resolved separately in #36477.

Props: adamsilverstein, pixlpirate, flixos90, mukesh27, azaozz.

Fixes #62900.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/image.php

    r59379 r59844  
    262262        }
    263263
    264         // Do not scale (large) PNG images. May result in sub-sizes that have greater file size than the original. See #48736.
    265         if ( 'image/png' !== $imagesize['mime'] ) {
    266 
    267                 /**
    268                  * Filters the "BIG image" threshold value.
    269                  *
    270                  * If the original image width or height is above the threshold, it will be scaled down. The threshold is
    271                  * used as max width and max height. The scaled down image will be used as the largest available size, including
    272                  * the `_wp_attached_file` post meta value.
    273                  *
    274                  * Returning `false` from the filter callback will disable the scaling.
    275                  *
    276                  * @since 5.3.0
    277                  *
    278                  * @param int    $threshold     The threshold value in pixels. Default 2560.
    279                  * @param array  $imagesize     {
    280                  *     Indexed array of the image width and height in pixels.
    281                  *
    282                  *     @type int $0 The image width.
    283                  *     @type int $1 The image height.
    284                  * }
    285                  * @param string $file          Full path to the uploaded image file.
    286                  * @param int    $attachment_id Attachment post ID.
    287                  */
    288                 $threshold = (int) apply_filters( 'big_image_size_threshold', 2560, $imagesize, $file, $attachment_id );
    289 
    290                 /*
    291                  * If the original image's dimensions are over the threshold,
    292                  * scale the image and use it as the "full" size.
    293                  */
    294                 $scale_down = false;
    295                 $convert    = false;
    296 
    297                 if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) {
    298                         // The image will be converted if needed on saving.
    299                         $scale_down = true;
    300                 } else {
    301                         // The image may need to be converted regardless of its dimensions.
    302                         $output_format = wp_get_image_editor_output_format( $file, $imagesize['mime'] );
    303 
    304                         if (
    305                                 is_array( $output_format ) &&
    306                                 array_key_exists( $imagesize['mime'], $output_format ) &&
    307                                 $output_format[ $imagesize['mime'] ] !== $imagesize['mime']
    308                         ) {
    309                                 $convert = true;
    310                         }
    311                 }
    312 
    313                 if ( $scale_down || $convert ) {
    314                         $editor = wp_get_image_editor( $file );
    315 
    316                         if ( is_wp_error( $editor ) ) {
    317                                 // This image cannot be edited.
    318                                 return $image_meta;
    319                         }
    320 
     264        /**
     265         * Filters the "BIG image" threshold value.
     266         *
     267         * If the original image width or height is above the threshold, it will be scaled down. The threshold is
     268         * used as max width and max height. The scaled down image will be used as the largest available size, including
     269         * the `_wp_attached_file` post meta value.
     270         *
     271         * Returning `false` from the filter callback will disable the scaling.
     272         *
     273         * @since 5.3.0
     274         *
     275         * @param int    $threshold     The threshold value in pixels. Default 2560.
     276         * @param array  $imagesize     {
     277         *     Indexed array of the image width and height in pixels.
     278         *
     279         *     @type int $0 The image width.
     280         *     @type int $1 The image height.
     281         * }
     282         * @param string $file          Full path to the uploaded image file.
     283         * @param int    $attachment_id Attachment post ID.
     284         */
     285        $threshold = (int) apply_filters( 'big_image_size_threshold', 2560, $imagesize, $file, $attachment_id );
     286
     287        /*
     288         * If the original image's dimensions are over the threshold,
     289         * scale the image and use it as the "full" size.
     290         */
     291        $scale_down = false;
     292        $convert    = false;
     293
     294        if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) {
     295                // The image will be converted if needed on saving.
     296                $scale_down = true;
     297        } else {
     298                // The image may need to be converted regardless of its dimensions.
     299                $output_format = wp_get_image_editor_output_format( $file, $imagesize['mime'] );
     300
     301                if (
     302                        is_array( $output_format ) &&
     303                        array_key_exists( $imagesize['mime'], $output_format ) &&
     304                        $output_format[ $imagesize['mime'] ] !== $imagesize['mime']
     305                ) {
     306                        $convert = true;
     307                }
     308        }
     309
     310        if ( $scale_down || $convert ) {
     311                $editor = wp_get_image_editor( $file );
     312
     313                if ( is_wp_error( $editor ) ) {
     314                        // This image cannot be edited.
     315                        return $image_meta;
     316                }
     317
     318                if ( $scale_down ) {
     319                        // Resize the image. This will also convet it if needed.
     320                        $resized = $editor->resize( $threshold, $threshold );
     321                } elseif ( $convert ) {
     322                        // The image will be converted (if possible) when saved.
     323                        $resized = true;
     324                }
     325
     326                $rotated = null;
     327
     328                // If there is EXIF data, rotate according to EXIF Orientation.
     329                if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) {
     330                        $resized = $editor->maybe_exif_rotate();
     331                        $rotated = $resized; // bool true or WP_Error
     332                }
     333
     334                if ( ! is_wp_error( $resized ) ) {
     335                        /*
     336                         * Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
     337                         * This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
     338                         */
    321339                        if ( $scale_down ) {
    322                                 // Resize the image. This will also convet it if needed.
    323                                 $resized = $editor->resize( $threshold, $threshold );
     340                                $saved = $editor->save( $editor->generate_filename( 'scaled' ) );
    324341                        } elseif ( $convert ) {
    325                                 // The image will be converted (if possible) when saved.
    326                                 $resized = true;
    327                         }
    328 
    329                         $rotated = null;
    330 
    331                         // If there is EXIF data, rotate according to EXIF Orientation.
    332                         if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) {
    333                                 $resized = $editor->maybe_exif_rotate();
    334                                 $rotated = $resized; // bool true or WP_Error
    335                         }
    336 
    337                         if ( ! is_wp_error( $resized ) ) {
    338342                                /*
    339                                  * Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
    340                                  * This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
     343                                 * Generate a new file name for the converted image.
     344                                 *
     345                                 * As the image file name will be unique due to the changed file extension,
     346                                 * it does not need a suffix to be unique. However, the generate_filename method
     347                                 * does not allow for an empty suffix, so the "-converted" suffix is required to
     348                                 * be added and subsequently removed.
    341349                                 */
    342                                 if ( $scale_down ) {
    343                                         $saved = $editor->save( $editor->generate_filename( 'scaled' ) );
    344                                 } elseif ( $convert ) {
    345                                         /*
    346                                          * Generate a new file name for the converted image.
    347                                          *
    348                                          * As the image file name will be unique due to the changed file extension,
    349                                          * it does not need a suffix to be unique. However, the generate_filename method
    350                                          * does not allow for an empty suffix, so the "-converted" suffix is required to
    351                                          * be added and subsequently removed.
    352                                          */
    353                                         $converted_file_name = $editor->generate_filename( 'converted' );
    354                                         $converted_file_name = preg_replace( '/(-converted\.)([a-z0-9]+)$/i', '.$2', $converted_file_name );
    355                                         $saved               = $editor->save( $converted_file_name );
    356                                 } else {
    357                                         $saved = $editor->save();
    358                                 }
    359 
    360                                 if ( ! is_wp_error( $saved ) ) {
    361                                         $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
    362 
    363                                         // If the image was rotated update the stored EXIF data.
    364                                         if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
    365                                                 $image_meta['image_meta']['orientation'] = 1;
    366                                         }
    367                                 } else {
    368                                         // TODO: Log errors.
     350                                $converted_file_name = $editor->generate_filename( 'converted' );
     351                                $converted_file_name = preg_replace( '/(-converted\.)([a-z0-9]+)$/i', '.$2', $converted_file_name );
     352                                $saved               = $editor->save( $converted_file_name );
     353                        } else {
     354                                $saved = $editor->save();
     355                        }
     356
     357                        if ( ! is_wp_error( $saved ) ) {
     358                                $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
     359
     360                                // If the image was rotated update the stored EXIF data.
     361                                if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
     362                                        $image_meta['image_meta']['orientation'] = 1;
    369363                                }
    370364                        } else {
    371365                                // TODO: Log errors.
    372366                        }
    373                 } elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) {
     367                } else {
     368                        // TODO: Log errors.
     369                }
     370        } elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) {
    374371                        // Rotate the whole original image if there is EXIF data and "orientation" is not 1.
    375372
    376373                        $editor = wp_get_image_editor( $file );
    377374
    378                         if ( is_wp_error( $editor ) ) {
    379                                 // This image cannot be edited.
    380                                 return $image_meta;
    381                         }
     375                if ( is_wp_error( $editor ) ) {
     376                        // This image cannot be edited.
     377                        return $image_meta;
     378                }
    382379
    383380                        // Rotate the image.
    384381                        $rotated = $editor->maybe_exif_rotate();
    385382
    386                         if ( true === $rotated ) {
    387                                 // Append `-rotated` to the image file name.
    388                                 $saved = $editor->save( $editor->generate_filename( 'rotated' ) );
    389 
    390                                 if ( ! is_wp_error( $saved ) ) {
    391                                         $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
    392 
    393                                         // Update the stored EXIF data.
    394                                         if ( ! empty( $image_meta['image_meta']['orientation'] ) ) {
    395                                                 $image_meta['image_meta']['orientation'] = 1;
    396                                         }
    397                                 } else {
    398                                         // TODO: Log errors.
     383                if ( true === $rotated ) {
     384                        // Append `-rotated` to the image file name.
     385                        $saved = $editor->save( $editor->generate_filename( 'rotated' ) );
     386
     387                        if ( ! is_wp_error( $saved ) ) {
     388                                $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
     389
     390                                // Update the stored EXIF data.
     391                                if ( ! empty( $image_meta['image_meta']['orientation'] ) ) {
     392                                        $image_meta['image_meta']['orientation'] = 1;
    399393                                }
     394                        } else {
     395                                // TODO: Log errors.
    400396                        }
    401397                }
Note: See TracChangeset for help on using the changeset viewer.