--- a/wp/wp-includes/class-wp-image-editor-gd.php Fri Sep 05 18:40:08 2025 +0200
+++ b/wp/wp-includes/class-wp-image-editor-gd.php Fri Sep 05 18:52:52 2025 +0200
@@ -103,20 +103,13 @@
return new WP_Error( 'error_loading_image', __( 'File does not exist?' ), $this->file );
}
- // WebP may not work with imagecreatefromstring().
+ // Handle WebP and AVIF mime types explicitly, falling back to imagecreatefromstring.
if (
- function_exists( 'imagecreatefromwebp' ) &&
- ( 'image/webp' === wp_get_image_mime( $this->file ) )
+ function_exists( 'imagecreatefromwebp' ) && ( 'image/webp' === wp_get_image_mime( $this->file ) )
) {
$this->image = @imagecreatefromwebp( $this->file );
- } else {
- $this->image = @imagecreatefromstring( $file_contents );
- }
-
- // AVIF may not work with imagecreatefromstring().
- if (
- function_exists( 'imagecreatefromavif' ) &&
- ( 'image/avif' === wp_get_image_mime( $this->file ) )
+ } elseif (
+ function_exists( 'imagecreatefromavif' ) && ( 'image/avif' === wp_get_image_mime( $this->file ) )
) {
$this->image = @imagecreatefromavif( $this->file );
} else {
@@ -182,7 +175,7 @@
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location:
*
- * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
+ * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'.
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
* }
* @return true|WP_Error
@@ -214,7 +207,7 @@
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location:
*
- * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
+ * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'.
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
* }
* @return resource|GdImage|WP_Error
@@ -228,6 +221,14 @@
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 );
@@ -572,6 +573,40 @@
}
/**
+ * 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 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, $dims = array() ) {
+ $quality_result = parent::set_quality( $quality, $dims );
+ if ( is_wp_error( $quality_result ) ) {
+ return $quality_result;
+ } else {
+ $quality = $this->get_quality();
+ }
+
+ // Handle setting the quality for WebP lossless images, see https://php.watch/versions/8.1/gd-webp-lossless.
+ try {
+ if ( 'image/webp' === $this->mime_type && defined( 'IMG_WEBP_LOSSLESS' ) ) {
+ $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, $dims );
+ }
+ }
+ } catch ( Exception $e ) {
+ return new WP_Error( 'image_quality_error', $e->getMessage() );
+ }
+ $this->quality = $quality;
+ return true;
+ }
+
+ /**
* Returns stream of current image.
*
* @since 3.5.0