diff -r 34716fd837a4 -r be944660c56a wp/wp-includes/class-wp-image-editor.php --- a/wp/wp-includes/class-wp-image-editor.php Tue Dec 15 15:52:01 2020 +0100 +++ b/wp/wp-includes/class-wp-image-editor.php Wed Sep 21 18:19:35 2022 +0200 @@ -15,9 +15,12 @@ protected $file = null; protected $size = null; protected $mime_type = null; + protected $output_mime_type = null; protected $default_mime_type = 'image/jpeg'; protected $quality = false; - protected $default_quality = 82; + + // Deprecated since 5.8.1. See get_default_quality() below. + protected $default_quality = 82; /** * Each instance handles a single file. @@ -64,7 +67,7 @@ * @since 3.5.0 * @abstract * - * @return bool|WP_Error True if loaded; WP_Error on failure. + * @return true|WP_Error True if loaded; WP_Error on failure. */ abstract public function load(); @@ -93,7 +96,7 @@ * @param int|null $max_w Image width. * @param int|null $max_h Image height. * @param bool $crop - * @return bool|WP_Error + * @return true|WP_Error */ abstract public function resize( $max_w, $max_h, $crop = false ); @@ -129,7 +132,7 @@ * @param int $dst_w Optional. The destination width. * @param int $dst_h Optional. The destination height. * @param bool $src_abs Optional. If the source crop points are absolute. - * @return bool|WP_Error + * @return true|WP_Error */ abstract public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false ); @@ -140,7 +143,7 @@ * @abstract * * @param float $angle - * @return bool|WP_Error + * @return true|WP_Error */ abstract public function rotate( $angle ); @@ -152,7 +155,7 @@ * * @param bool $horz Flip along Horizontal Axis * @param bool $vert Flip along Vertical Axis - * @return bool|WP_Error + * @return true|WP_Error */ abstract public function flip( $horz, $vert ); @@ -163,7 +166,7 @@ * @abstract * * @param string $mime_type The mime type of the image. - * @return bool|WP_Error True on success, WP_Error object or false on failure. + * @return true|WP_Error True on success, WP_Error object on failure. */ abstract public function stream( $mime_type = null ); @@ -224,6 +227,11 @@ * @return true|WP_Error True if set successfully; WP_Error on failure. */ public function set_quality( $quality = null ) { + // 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. + $default_quality = $this->get_default_quality( $mime_type ); + if ( null === $quality ) { /** * Filters the default image compression quality setting. @@ -238,9 +246,9 @@ * @param int $quality Quality level between 1 (low) and 100 (high). * @param string $mime_type Image mime type. */ - $quality = apply_filters( 'wp_editor_set_quality', $this->default_quality, $this->mime_type ); + $quality = apply_filters( 'wp_editor_set_quality', $default_quality, $mime_type ); - if ( 'image/jpeg' === $this->mime_type ) { + if ( 'image/jpeg' === $mime_type ) { /** * Filters the JPEG compression quality for backward-compatibility. * @@ -261,7 +269,7 @@ } if ( $quality < 0 || $quality > 100 ) { - $quality = $this->default_quality; + $quality = $default_quality; } } @@ -279,6 +287,27 @@ } /** + * Returns the default compression quality setting for the mime type. + * + * @since 5.8.1 + * + * @param string $mime_type + * @return int The default quality setting for the mime type. + */ + protected function get_default_quality( $mime_type ) { + switch ( $mime_type ) { + case 'image/webp': + $quality = 86; + break; + case 'image/jpeg': + default: + $quality = $this->default_quality; + } + + return $quality; + } + + /** * Returns preferred mime-type and extension based on provided * file's extension and mime, or current file's extension and mime. * @@ -316,6 +345,35 @@ $new_ext = $file_ext; } + /** + * Filters the image editor output format mapping. + * + * Enables filtering the mime type used to save images. By default, + * the mapping array is empty, so the mime type matches the source image. + * + * @see WP_Image_Editor::get_output_format() + * + * @since 5.8.0 + * + * @param string[] $output_format { + * An array of mime type mappings. Maps a source mime type to a new + * destination mime type. Default empty array. + * + * @type string ...$0 The new mime type. + * } + * @param string $filename Path to the image. + * @param string $mime_type The source image mime type. + * } + */ + $output_format = apply_filters( 'image_editor_output_format', array(), $filename, $mime_type ); + + if ( isset( $output_format[ $mime_type ] ) + && $this->supports_mime_type( $output_format[ $mime_type ] ) + ) { + $mime_type = $output_format[ $mime_type ]; + $new_ext = $this->get_extension( $mime_type ); + } + // Double-check that the mime-type selected is supported by the editor. // If not, choose a default instead. if ( ! $this->supports_mime_type( $mime_type ) ) { @@ -332,13 +390,28 @@ $new_ext = $this->get_extension( $mime_type ); } - if ( $filename ) { + // Ensure both $filename and $new_ext are not empty. + // $this->get_extension() returns false on error which would effectively remove the extension + // from $filename. That shouldn't happen, files without extensions are not supported. + if ( $filename && $new_ext ) { $dir = pathinfo( $filename, PATHINFO_DIRNAME ); $ext = pathinfo( $filename, PATHINFO_EXTENSION ); $filename = trailingslashit( $dir ) . wp_basename( $filename, ".$ext" ) . ".{$new_ext}"; } + if ( $mime_type && ( $mime_type !== $this->mime_type ) ) { + // The image will be converted when saving. Set the quality for the new mime-type if not already set. + if ( $mime_type !== $this->output_mime_type ) { + $this->output_mime_type = $mime_type; + $this->set_quality(); + } + } elseif ( ! empty( $this->output_mime_type ) ) { + // Reset output_mime_type and quality. + $this->output_mime_type = null; + $this->set_quality(); + } + return array( $filename, $new_ext, $mime_type ); } @@ -365,9 +438,13 @@ $new_ext = strtolower( $extension ? $extension : $ext ); if ( ! is_null( $dest_path ) ) { - $_dest_path = realpath( $dest_path ); - if ( $_dest_path ) { - $dir = $_dest_path; + if ( ! wp_is_stream( $dest_path ) ) { + $_dest_path = realpath( $dest_path ); + if ( $_dest_path ) { + $dir = $_dest_path; + } + } else { + $dir = $dest_path; } } @@ -545,13 +622,11 @@ * @return string|false */ protected static function get_extension( $mime_type = null ) { - $extensions = explode( '|', array_search( $mime_type, wp_get_mime_types(), true ) ); - - if ( empty( $extensions[0] ) ) { + if ( empty( $mime_type ) ) { return false; } - return $extensions[0]; + return wp_get_default_extension_for_mime_type( $mime_type ); } }