101 |
101 |
102 if ( ! $file_contents ) { |
102 if ( ! $file_contents ) { |
103 return new WP_Error( 'error_loading_image', __( 'File does not exist?' ), $this->file ); |
103 return new WP_Error( 'error_loading_image', __( 'File does not exist?' ), $this->file ); |
104 } |
104 } |
105 |
105 |
106 // WebP may not work with imagecreatefromstring(). |
106 // Handle WebP and AVIF mime types explicitly, falling back to imagecreatefromstring. |
107 if ( |
107 if ( |
108 function_exists( 'imagecreatefromwebp' ) && |
108 function_exists( 'imagecreatefromwebp' ) && ( 'image/webp' === wp_get_image_mime( $this->file ) ) |
109 ( 'image/webp' === wp_get_image_mime( $this->file ) ) |
|
110 ) { |
109 ) { |
111 $this->image = @imagecreatefromwebp( $this->file ); |
110 $this->image = @imagecreatefromwebp( $this->file ); |
112 } else { |
111 } elseif ( |
113 $this->image = @imagecreatefromstring( $file_contents ); |
112 function_exists( 'imagecreatefromavif' ) && ( 'image/avif' === wp_get_image_mime( $this->file ) ) |
114 } |
|
115 |
|
116 // AVIF may not work with imagecreatefromstring(). |
|
117 if ( |
|
118 function_exists( 'imagecreatefromavif' ) && |
|
119 ( 'image/avif' === wp_get_image_mime( $this->file ) ) |
|
120 ) { |
113 ) { |
121 $this->image = @imagecreatefromavif( $this->file ); |
114 $this->image = @imagecreatefromavif( $this->file ); |
122 } else { |
115 } else { |
123 $this->image = @imagecreatefromstring( $file_contents ); |
116 $this->image = @imagecreatefromstring( $file_contents ); |
124 } |
117 } |
180 * @param bool|array $crop { |
173 * @param bool|array $crop { |
181 * Optional. Image cropping behavior. If false, the image will be scaled (default). |
174 * Optional. Image cropping behavior. If false, the image will be scaled (default). |
182 * If true, image will be cropped to the specified dimensions using center positions. |
175 * If true, image will be cropped to the specified dimensions using center positions. |
183 * If an array, the image will be cropped using the array to specify the crop location: |
176 * If an array, the image will be cropped using the array to specify the crop location: |
184 * |
177 * |
185 * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. |
178 * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'. |
186 * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. |
179 * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. |
187 * } |
180 * } |
188 * @return true|WP_Error |
181 * @return true|WP_Error |
189 */ |
182 */ |
190 public function resize( $max_w, $max_h, $crop = false ) { |
183 public function resize( $max_w, $max_h, $crop = false ) { |
212 * @param bool|array $crop { |
205 * @param bool|array $crop { |
213 * Optional. Image cropping behavior. If false, the image will be scaled (default). |
206 * Optional. Image cropping behavior. If false, the image will be scaled (default). |
214 * If true, image will be cropped to the specified dimensions using center positions. |
207 * If true, image will be cropped to the specified dimensions using center positions. |
215 * If an array, the image will be cropped using the array to specify the crop location: |
208 * If an array, the image will be cropped using the array to specify the crop location: |
216 * |
209 * |
217 * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. |
210 * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'. |
218 * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. |
211 * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. |
219 * } |
212 * } |
220 * @return resource|GdImage|WP_Error |
213 * @return resource|GdImage|WP_Error |
221 */ |
214 */ |
222 protected function _resize( $max_w, $max_h, $crop = false ) { |
215 protected function _resize( $max_w, $max_h, $crop = false ) { |
225 if ( ! $dims ) { |
218 if ( ! $dims ) { |
226 return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->file ); |
219 return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->file ); |
227 } |
220 } |
228 |
221 |
229 list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; |
222 list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; |
|
223 |
|
224 $this->set_quality( |
|
225 null, |
|
226 array( |
|
227 'width' => $dst_w, |
|
228 'height' => $dst_h, |
|
229 ) |
|
230 ); |
230 |
231 |
231 $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); |
232 $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); |
232 imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); |
233 imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); |
233 |
234 |
234 if ( is_gd_image( $resized ) ) { |
235 if ( is_gd_image( $resized ) ) { |
567 'width' => $this->size['width'], |
568 'width' => $this->size['width'], |
568 'height' => $this->size['height'], |
569 'height' => $this->size['height'], |
569 'mime-type' => $mime_type, |
570 'mime-type' => $mime_type, |
570 'filesize' => wp_filesize( $filename ), |
571 'filesize' => wp_filesize( $filename ), |
571 ); |
572 ); |
|
573 } |
|
574 |
|
575 /** |
|
576 * Sets Image Compression quality on a 1-100% scale. Handles WebP lossless images. |
|
577 * |
|
578 * @since 6.7.0 |
|
579 * @since 6.8.0 The `$dims` parameter was added. |
|
580 * |
|
581 * @param int $quality Compression Quality. Range: [1,100] |
|
582 * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys. |
|
583 * @return true|WP_Error True if set successfully; WP_Error on failure. |
|
584 */ |
|
585 public function set_quality( $quality = null, $dims = array() ) { |
|
586 $quality_result = parent::set_quality( $quality, $dims ); |
|
587 if ( is_wp_error( $quality_result ) ) { |
|
588 return $quality_result; |
|
589 } else { |
|
590 $quality = $this->get_quality(); |
|
591 } |
|
592 |
|
593 // Handle setting the quality for WebP lossless images, see https://php.watch/versions/8.1/gd-webp-lossless. |
|
594 try { |
|
595 if ( 'image/webp' === $this->mime_type && defined( 'IMG_WEBP_LOSSLESS' ) ) { |
|
596 $webp_info = wp_get_webp_info( $this->file ); |
|
597 if ( ! empty( $webp_info['type'] ) && 'lossless' === $webp_info['type'] ) { |
|
598 $quality = IMG_WEBP_LOSSLESS; |
|
599 parent::set_quality( $quality, $dims ); |
|
600 } |
|
601 } |
|
602 } catch ( Exception $e ) { |
|
603 return new WP_Error( 'image_quality_error', $e->getMessage() ); |
|
604 } |
|
605 $this->quality = $quality; |
|
606 return true; |
572 } |
607 } |
573 |
608 |
574 /** |
609 /** |
575 * Returns stream of current image. |
610 * Returns stream of current image. |
576 * |
611 * |