diff --git a/src/wp-includes/class-wp-image-editor-gd.php b/src/wp-includes/class-wp-image-editor-gd.php index e4f065537639d..47ba91a367d9f 100644 --- a/src/wp-includes/class-wp-image-editor-gd.php +++ b/src/wp-includes/class-wp-image-editor-gd.php @@ -221,6 +221,14 @@ protected function _resize( $max_w, $max_h, $crop = false ) { list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; + $this->set_quality( + null, + array( + 'width' => $dst_w, + 'height' => $dst_h, + ) + ); + $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); @@ -568,12 +576,14 @@ protected function _save( $image, $filename = null, $mime_type = null ) { * Sets Image Compression quality on a 1-100% scale. Handles WebP lossless images. * * @since 6.7.0 + * @since 6.8.0 The `$dims` parameter was added. * - * @param int $quality Compression Quality. Range: [1,100] + * @param int $quality Compression Quality. Range: [1,100] + * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys. * @return true|WP_Error True if set successfully; WP_Error on failure. */ - public function set_quality( $quality = null ) { - $quality_result = parent::set_quality( $quality ); + public function set_quality( $quality = null, $dims = array() ) { + $quality_result = parent::set_quality( $quality, $dims ); if ( is_wp_error( $quality_result ) ) { return $quality_result; } else { @@ -586,7 +596,7 @@ public function set_quality( $quality = null ) { $webp_info = wp_get_webp_info( $this->file ); if ( ! empty( $webp_info['type'] ) && 'lossless' === $webp_info['type'] ) { $quality = IMG_WEBP_LOSSLESS; - parent::set_quality( $quality ); + parent::set_quality( $quality, $dims ); } } } catch ( Exception $e ) { diff --git a/src/wp-includes/class-wp-image-editor-imagick.php b/src/wp-includes/class-wp-image-editor-imagick.php index 45b0e3a5a48ef..dd8b9ad5191ee 100644 --- a/src/wp-includes/class-wp-image-editor-imagick.php +++ b/src/wp-includes/class-wp-image-editor-imagick.php @@ -190,12 +190,14 @@ public function load() { * Sets Image Compression quality on a 1-100% scale. * * @since 3.5.0 + * @since 6.8.0 The `$dims` parameter was added. * - * @param int $quality Compression Quality. Range: [1,100] + * @param int $quality Compression Quality. Range: [1,100] + * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys. * @return true|WP_Error True if set successfully; WP_Error on failure. */ - public function set_quality( $quality = null ) { - $quality_result = parent::set_quality( $quality ); + public function set_quality( $quality = null, $dims = array() ) { + $quality_result = parent::set_quality( $quality, $dims ); if ( is_wp_error( $quality_result ) ) { return $quality_result; } else { @@ -367,6 +369,14 @@ public function resize( $max_w, $max_h, $crop = false ) { return $this->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h ); } + $this->set_quality( + null, + array( + 'width' => $dst_w, + 'height' => $dst_h, + ) + ); + // Execute the resize. $thumb_result = $this->thumbnail_image( $dst_w, $dst_h ); if ( is_wp_error( $thumb_result ) ) { diff --git a/src/wp-includes/class-wp-image-editor.php b/src/wp-includes/class-wp-image-editor.php index dc2420507800d..f9f58fcd50c6b 100644 --- a/src/wp-includes/class-wp-image-editor.php +++ b/src/wp-includes/class-wp-image-editor.php @@ -240,11 +240,14 @@ public function get_quality() { * Sets Image Compression quality on a 1-100% scale. * * @since 3.5.0 + * @since 6.8.0 The `$dims` parameter was added. * - * @param int $quality Compression Quality. Range: [1,100] + * @param int $quality Compression Quality. Range: [1,100] + * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys. * @return true|WP_Error True if set successfully; WP_Error on failure. + */ - public function set_quality( $quality = null ) { + public function set_quality( $quality = null, $dims = array() ) { // Use the output mime type if present. If not, fall back to the input/initial mime type. $mime_type = ! empty( $this->output_mime_type ) ? $this->output_mime_type : $this->mime_type; // Get the default quality setting for the mime type. @@ -260,11 +263,18 @@ public function set_quality( $quality = null ) { * The WP_Image_Editor::set_quality() method has priority over the filter. * * @since 3.5.0 + * @since 6.8.0 Added the size parameter. * * @param int $quality Quality level between 1 (low) and 100 (high). * @param string $mime_type Image mime type. + * @param array $size { + * Dimensions of the image. + * + * @type int $width The image width. + * @type int $height The image height. + * } */ - $quality = apply_filters( 'wp_editor_set_quality', $default_quality, $mime_type ); + $quality = apply_filters( 'wp_editor_set_quality', $default_quality, $mime_type, $dims ? $dims : $this->size ); if ( 'image/jpeg' === $mime_type ) { /** diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 41ae8ef216401..7b6dc5002f106 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -5433,6 +5433,51 @@ public function test_quality_with_avif_conversion_file_sizes() { } } + /** + * Test that the `wp_editor_set_quality` filter includes the dimensions in the `$dims` parameter. + * + * @ticket 54648 + */ + public function test_wp_editor_set_quality_includes_dimensions() { + // Before loading an image, set up the callback filter with the assertions. + add_filter( 'wp_editor_set_quality', array( $this, 'assert_dimensions_in_wp_editor_set_quality' ), 10, 3 ); + + $temp_dir = get_temp_dir(); + $file = $temp_dir . '/33772.jpg'; + copy( DIR_TESTDATA . '/images/33772.jpg', $file ); + + $editor = wp_get_image_editor( $file ); + + $attachment_id = self::factory()->attachment->create_object( + array( + 'post_mime_type' => 'image/jpeg', + 'file' => $file, + ) + ); + + // Generate all sizes. + wp_generate_attachment_metadata( $attachment_id, $file ); + + // Clean up the filter. + remove_filter( 'wp_editor_set_quality', array( $this, 'assert_dimensions_in_wp_editor_set_quality' ), 10, 3 ); + } + + /** + * Helper callback to assert that the dimensions are included in the `$dims` parameter. + * + * @param int $quality The quality level. + * @param array $dims The dimensions array. + */ + public function assert_dimensions_in_wp_editor_set_quality( $quality, $mime_type, $dims ) { + // Assert that the array has non empty width and height values. + $this->assertArrayHasKey( 'width', $dims ); + $this->assertArrayHasKey( 'height', $dims ); + $this->assertGreaterThan( 0, $dims['width'] ); + $this->assertGreaterThan( 0, $dims['height'] ); + + return $quality; + } + /** * Test that an image size isn't generated if it matches the original image size. *