Make WordPress Core

Changeset 51704 for trunk


Ignore:
Timestamp:
08/31/2021 06:57:09 PM (5 years ago)
Author:
azaozz
Message:

Media: apply the wp_editor_set_quality filter not only when loading an image in the editor but also when saving an converted image, after the mime-type of the output image has changed.

Props mikeschroder, desrosj, azaozz.
Fixes #53667.

Location:
trunk
Files:
3 edited

Legend:

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

    r51653 r51704  
    1616        protected $size              = null;
    1717        protected $mime_type         = null;
     18        protected $output_mime_type  = null;
    1819        protected $default_mime_type = 'image/jpeg';
    1920        protected $quality           = false;
    20         protected $default_quality   = 82;
     21
     22        // Deprecated since 5.8.1. See get_default_quality() below.
     23        protected $default_quality = 82;
    2124
    2225        /**
     
    225228         */
    226229        public function set_quality( $quality = null ) {
     230                // Use the output mime type if present. If not, fall back to the input/initial mime type.
     231                $mime_type = ! empty( $this->output_mime_type ) ? $this->output_mime_type : $this->mime_type;
     232                // Get the default quality setting for the mime type.
     233                $default_quality = $this->get_default_quality( $mime_type );
     234
    227235                if ( null === $quality ) {
    228236                        /**
     
    239247                         * @param string $mime_type Image mime type.
    240248                         */
    241                         $quality = apply_filters( 'wp_editor_set_quality', $this->default_quality, $this->mime_type );
    242 
    243                         if ( 'image/jpeg' === $this->mime_type ) {
     249                        $quality = apply_filters( 'wp_editor_set_quality', $default_quality, $mime_type );
     250
     251                        if ( 'image/jpeg' === $mime_type ) {
    244252                                /**
    245253                                 * Filters the JPEG compression quality for backward-compatibility.
     
    262270
    263271                        if ( $quality < 0 || $quality > 100 ) {
    264                                 $quality = $this->default_quality;
     272                                $quality = $default_quality;
    265273                        }
    266274                }
     
    277285                        return new WP_Error( 'invalid_image_quality', __( 'Attempted to set image quality outside of the range [1,100].' ) );
    278286                }
     287        }
     288
     289        /**
     290         * Returns the default compression quality setting for the mime type.
     291         *
     292         * @since 5.8.1
     293         *
     294         * @param string $mime_type
     295         * @return int The default quality setting for the mime type.
     296         */
     297        protected function get_default_quality( $mime_type ) {
     298                switch ( $mime_type ) {
     299                        case 'image/webp':
     300                                $quality = 86;
     301                                break;
     302                        case 'image/jpeg':
     303                        default:
     304                                $quality = $this->default_quality;
     305                }
     306
     307                return $quality;
    279308        }
    280309
     
    375404                }
    376405
    377                 if ( $filename ) {
     406                // Ensure both $filename and $new_ext are not empty.
     407                // $this->get_extension() returns false on error which would effectively remove the extension
     408                // from $filename. That shouldn't happen, files without extensions are not supported.
     409                if ( $filename && $new_ext ) {
    378410                        $dir = pathinfo( $filename, PATHINFO_DIRNAME );
    379411                        $ext = pathinfo( $filename, PATHINFO_EXTENSION );
    380412
    381413                        $filename = trailingslashit( $dir ) . wp_basename( $filename, ".$ext" ) . ".{$new_ext}";
     414                }
     415
     416                if ( $mime_type && ( $mime_type !== $this->mime_type ) ) {
     417                        // The image will be converted when saving. Set the quality for the new mime-type if not already set.
     418                        if ( $mime_type !== $this->output_mime_type ) {
     419                                $this->output_mime_type = $mime_type;
     420                                $this->set_quality();
     421                        }
     422                } elseif ( ! empty( $this->output_mime_type ) ) {
     423                        // Reset output_mime_type and quality.
     424                        $this->output_mime_type = null;
     425                        $this->set_quality();
    382426                }
    383427
  • trunk/tests/phpunit/includes/mock-image-editor.php

    r48291 r51704  
    5757                }
    5858                public function save( $destfilename = null, $mime_type = null ) {
     59                        // Set new mime-type and quality if converting the image.
     60                        $this->get_output_format( $destfilename, $mime_type );
    5961                        return self::$save_return;
    6062                }
  • trunk/tests/phpunit/tests/image/editor.php

    r51568 r51704  
    112112
    113113        /**
     114         * Test test_quality when converting image
     115         *
     116         * @ticket 6821
     117         */
     118        public function test_set_quality_with_image_conversion() {
     119                $editor = wp_get_image_editor( DIR_TESTDATA . '/images/test-image.png' );
     120                $editor->set_mime_type( 'image/png' ); // Ensure mime-specific filters act properly.
     121
     122                // Set conversions for uploaded images.
     123                add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) );
     124
     125                // Quality setting for the source image. For PNG the fallback default of 82 is used.
     126                $this->assertSame( 82, $editor->get_quality(), 'Default quality setting is 82.' );
     127
     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.
     134                remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) );
     135                $editor->save();
     136                $this->assertSame( 82, $editor->get_quality(), 'After removing image conversion quality setting should reset to the default of 82.' );
     137
     138                unset( $editor );
     139
     140                // Set conversions for uploaded images.
     141                add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) );
     142                // Change the quality values.
     143                add_filter( 'wp_editor_set_quality', array( $this, 'image_editor_change_quality' ), 10, 2 );
     144
     145                // Get a new editor to clear quality state.
     146                $editor = wp_get_image_editor( DIR_TESTDATA . '/images/test-image.jpg' );
     147                $editor->set_mime_type( 'image/jpeg' );
     148
     149                $this->assertSame( 56, $editor->get_quality(), 'Filtered default quality for JPEG is 56.' );
     150
     151                // 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.' );
     155
     156                // After removing the conversion the quality setting should reset to the filtered value for the original image type, JPEG.
     157                remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) );
     158                $editor->save();
     159                $this->assertSame(
     160                        56,
     161                        $editor->get_quality(),
     162                        'After removing image conversion the quality setting should reset to the filtered value for JPEG, 56.'
     163                );
     164
     165                remove_filter( 'wp_editor_set_quality', array( $this, 'image_editor_change_quality' ) );
     166        }
     167
     168        /**
     169         * Changes the output format when editing images. PNG and JPEG files
     170         * will be converted to WEBP (if the image editor in PHP supports it).
     171         *
     172         * @param array $formats
     173         *
     174         * @return array
     175         */
     176        public function image_editor_output_formats( $formats ) {
     177                $formats['image/png']  = 'image/webp';
     178                $formats['image/jpeg'] = 'image/webp';
     179                return $formats;
     180        }
     181
     182        /**
     183         * Changes the quality according to the mime-type.
     184         *
     185         * @param int    $quality   Default quality.
     186         * @param string $mime_type Image mime-type.
     187         * @return int The changed quality.
     188         */
     189        public function image_editor_change_quality( $quality, $mime_type ) {
     190                if ( 'image/jpeg' === $mime_type ) {
     191                        return 56;
     192                } elseif ( 'image/webp' === $mime_type ) {
     193                        return 42;
     194                } else {
     195                        return 30;
     196                }
     197        }
     198
     199        /**
    114200         * Test generate_filename
    115201         *
Note: See TracChangeset for help on using the changeset viewer.