Make WordPress Core

Changeset 54417


Ignore:
Timestamp:
10/07/2022 07:15:59 PM (3 years ago)
Author:
adamsilverstein
Message:

Media: ensure the wp_editor_set_quality filter consistently passes the correct output mime type.

Ensure that the mime type passed to the wp_editor_set_quality filter is correct when the output format is altered with the image_editor_output_format filter and the image is saved multiple times, for example when generating sub sizes. Previously, the original image mime type was passed instead of the output type after the initial save.

Props flixos90, peterwilsoncc.
Fixes #56442.

Location:
trunk
Files:
3 edited

Legend:

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

    r54265 r54417  
    415415            if ( $mime_type !== $this->output_mime_type ) {
    416416                $this->output_mime_type = $mime_type;
    417                 $this->set_quality();
    418417            }
     418            $this->set_quality();
    419419        } elseif ( ! empty( $this->output_mime_type ) ) {
    420420            // Reset output_mime_type and quality.
  • trunk/tests/phpunit/tests/image/editor.php

    r54226 r54417  
    106106        // Ensure wp_editor_set_quality filter applies if it exists before editor instantiation.
    107107        $this->assertSame( 100, $editor->get_quality() );
    108 
    109         // Clean up.
    110         remove_filter( 'wp_editor_set_quality', $func_100_percent );
    111108    }
    112109
     
    120117        $editor->set_mime_type( 'image/png' ); // Ensure mime-specific filters act properly.
    121118
     119        // Quality setting for the source image. For PNG the fallback default of 82 is used.
     120        $this->assertSame( 82, $editor->get_quality(), 'Default quality setting is 82.' );
     121
    122122        // Set conversions for uploaded images.
    123123        add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) );
     
    126126        $this->assertSame( 82, $editor->get_quality(), 'Default quality setting is 82.' );
    127127
    128         // Quality should change to the output format's value.
    129         // A PNG image will be converted to WEBP whose quialty should be 86.
    130         $editor->save();
    131         $this->assertSame( 86, $editor->get_quality(), 'Output image format is WEBP. Quality setting for it should be 86.' );
    132 
    133         // Removing PNG to WEBP conversion on save. Quality setting should reset to the default.
     128        // When saving, quality should change to the output format's value.
     129        // A PNG image will be converted to WebP whose quality should be 86.
     130        $editor->save();
     131        $this->assertSame( 86, $editor->get_quality(), 'Output image format is WebP. Quality setting for it should be 86.' );
     132
     133        // Saving again should not change the quality.
     134        $editor->save();
     135        $this->assertSame( 86, $editor->get_quality(), 'Output image format is WebP. Quality setting for it should be 86.' );
     136
     137        // Removing PNG to WebP conversion on save. Quality setting should reset to the default.
    134138        remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) );
    135139        $editor->save();
     
    150154
    151155        // Quality should change to the output format's value as filtered above.
    152         // A JPEG image will be converted to WEBP whose quialty should be 42.
    153         $editor->save();
    154         $this->assertSame( 42, $editor->get_quality(), 'Image conversion from JPEG to WEBP. Filtered WEBP quality shoild be 42.' );
     156        // A JPEG image will be converted to WebP whose quialty should be 42.
     157        $editor->save();
     158        $this->assertSame( 42, $editor->get_quality(), 'Image conversion from JPEG to WEBP. Filtered WEBP quality should be 42.' );
    155159
    156160        // After removing the conversion the quality setting should reset to the filtered value for the original image type, JPEG.
     
    162166            'After removing image conversion the quality setting should reset to the filtered value for JPEG, 56.'
    163167        );
    164 
    165         remove_filter( 'wp_editor_set_quality', array( $this, 'image_editor_change_quality' ) );
    166168    }
    167169
  • trunk/tests/phpunit/tests/media.php

    r54402 r54417  
    36223622        remove_filter( 'wp_omit_loading_attr_threshold', '__return_null', 100 );
    36233623    }
     3624
     3625    /**
     3626     * Test that generated files with the `image_editor_output_format` applied use the correct
     3627     * quality level based on their mime type.
     3628     *
     3629     * @ticket 56442
     3630     */
     3631    public function test_quality_with_image_conversion_file_sizes() {
     3632        add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_jpeg' ) );
     3633        $temp_dir = get_temp_dir();
     3634        $file     = $temp_dir . '/33772.jpg';
     3635        copy( DIR_TESTDATA . '/images/33772.jpg', $file );
     3636
     3637        // Set JPEG output quality very low and WebP quality very high, this should force all generated WebP images to
     3638        // be larger than the the matching generated JPEGs.
     3639        add_filter( 'wp_editor_set_quality', array( $this, 'image_editor_change_quality_low_jpeg' ), 10, 2 );
     3640
     3641        $editor = wp_get_image_editor( $file );
     3642
     3643        // Verify that the selected editor supports WebP output.
     3644        if ( ! $editor->supports_mime_type( 'image/webp' ) ) {
     3645            $this->markTestSkipped( 'WebP is not supported by the selected image editor.' );
     3646        }
     3647
     3648        $attachment_id = self::factory()->attachment->create_object(
     3649            array(
     3650                'post_mime_type' => 'image/jpeg',
     3651                'file'           => $file,
     3652            )
     3653        );
     3654
     3655        add_filter( 'big_image_size_threshold', array( $this, 'add_big_image_size_threshold' ) );
     3656
     3657        // Generate all sizes as JPEGs.
     3658        $jpeg_sizes = wp_generate_attachment_metadata( $attachment_id, $file );
     3659        remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_jpeg' ) );
     3660
     3661        // Generate all sizes as WebP.
     3662        add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_webp' ) );
     3663        $webp_sizes = wp_generate_attachment_metadata( $attachment_id, $file );
     3664        remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_webp' ) );
     3665
     3666        // The main (scaled) image: the JPEG should be smaller than the WebP.
     3667        $this->assertLessThan( $webp_sizes['filesize'], $jpeg_sizes['filesize'], 'The JPEG should be smaller than the WebP.' );
     3668
     3669        // Sub-sizes: for each size, the JPEGs should be smaller than the WebP.
     3670        $sizes_to_compare = array_intersect_key( $jpeg_sizes['sizes'], $webp_sizes['sizes'] );
     3671        foreach ( $sizes_to_compare as $size => $size_data ) {
     3672            $this->assertLessThan( $webp_sizes['sizes'][ $size ]['filesize'], $jpeg_sizes['sizes'][ $size ]['filesize'] );
     3673        }
     3674    }
     3675
     3676    /**
     3677     * Add threshold to create a `-scaled` output image for testing.
     3678     */
     3679    public function add_big_image_size_threshold() {
     3680        return 1000;
     3681    }
     3682
     3683    /**
     3684     * Output JPEG files.
     3685     */
     3686    public function image_editor_output_jpeg() {
     3687        return array( 'image/jpeg' => 'image/jpeg' );
     3688    }
     3689
     3690    /**
     3691     * Output WebP files.
     3692     */
     3693    public function image_editor_output_webp() {
     3694        return array( 'image/jpeg' => 'image/webp' );
     3695    }
     3696
     3697    /**
     3698     * Changes the quality using very low quality for JPEGs and very high quality
     3699     * for WebPs, used to verify the filter is applying correctly.
     3700     *
     3701     * @param int    $quality   Default quality.
     3702     * @param string $mime_type Image mime-type.
     3703     * @return int The changed quality.
     3704     */
     3705    public function image_editor_change_quality_low_jpeg( $quality, $mime_type ) {
     3706        if ( 'image/jpeg' === $mime_type ) {
     3707            return 1;
     3708        } elseif ( 'image/webp' === $mime_type ) {
     3709            return 100;
     3710        } else {
     3711            return 30;
     3712        }
     3713    }
     3714
    36243715}
    36253716
Note: See TracChangeset for help on using the changeset viewer.