wp/wp-includes/class-wp-image-editor.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     9 /**
     9 /**
    10  * Base image editor class from which implementations extend
    10  * Base image editor class from which implementations extend
    11  *
    11  *
    12  * @since 3.5.0
    12  * @since 3.5.0
    13  */
    13  */
       
    14 #[AllowDynamicProperties]
    14 abstract class WP_Image_Editor {
    15 abstract class WP_Image_Editor {
    15 	protected $file              = null;
    16 	protected $file              = null;
    16 	protected $size              = null;
    17 	protected $size              = null;
    17 	protected $mime_type         = null;
    18 	protected $mime_type         = null;
    18 	protected $output_mime_type  = null;
    19 	protected $output_mime_type  = null;
    73 
    74 
    74 	/**
    75 	/**
    75 	 * Saves current image to file.
    76 	 * Saves current image to file.
    76 	 *
    77 	 *
    77 	 * @since 3.5.0
    78 	 * @since 3.5.0
       
    79 	 * @since 6.0.0 The `$filesize` value was added to the returned array.
    78 	 * @abstract
    80 	 * @abstract
    79 	 *
    81 	 *
    80 	 * @param string $destfilename Optional. Destination filename. Default null.
    82 	 * @param string $destfilename Optional. Destination filename. Default null.
    81 	 * @param string $mime_type    Optional. The mime-type. Default null.
    83 	 * @param string $mime_type    Optional. The mime-type. Default null.
    82 	 * @return array|WP_Error {'path'=>string, 'file'=>string, 'width'=>int, 'height'=>int, 'mime-type'=>string}
    84 	 * @return array|WP_Error {
       
    85 	 *     Array on success or WP_Error if the file failed to save.
       
    86 	 *
       
    87 	 *     @type string $path      Path to the image file.
       
    88 	 *     @type string $file      Name of the image file.
       
    89 	 *     @type int    $width     Image width.
       
    90 	 *     @type int    $height    Image height.
       
    91 	 *     @type string $mime-type The mime type of the image.
       
    92 	 *     @type int    $filesize  File size of the image.
       
    93 	 * }
    83 	 */
    94 	 */
    84 	abstract public function save( $destfilename = null, $mime_type = null );
    95 	abstract public function save( $destfilename = null, $mime_type = null );
    85 
    96 
    86 	/**
    97 	/**
    87 	 * Resizes current image.
    98 	 * Resizes current image.
    91 	 * maintain aspect ratio according to the provided dimension.
   102 	 * maintain aspect ratio according to the provided dimension.
    92 	 *
   103 	 *
    93 	 * @since 3.5.0
   104 	 * @since 3.5.0
    94 	 * @abstract
   105 	 * @abstract
    95 	 *
   106 	 *
    96 	 * @param int|null $max_w Image width.
   107 	 * @param int|null   $max_w Image width.
    97 	 * @param int|null $max_h Image height.
   108 	 * @param int|null   $max_h Image height.
    98 	 * @param bool     $crop
   109 	 * @param bool|array $crop  {
       
   110 	 *     Optional. Image cropping behavior. If false, the image will be scaled (default).
       
   111 	 *     If true, image will be cropped to the specified dimensions using center positions.
       
   112 	 *     If an array, the image will be cropped using the array to specify the crop location:
       
   113 	 *
       
   114 	 *     @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
       
   115 	 *     @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
       
   116 	 * }
    99 	 * @return true|WP_Error
   117 	 * @return true|WP_Error
   100 	 */
   118 	 */
   101 	abstract public function resize( $max_w, $max_h, $crop = false );
   119 	abstract public function resize( $max_w, $max_h, $crop = false );
   102 
   120 
   103 	/**
   121 	/**
   108 	 *
   126 	 *
   109 	 * @param array $sizes {
   127 	 * @param array $sizes {
   110 	 *     An array of image size arrays. Default sizes are 'small', 'medium', 'large'.
   128 	 *     An array of image size arrays. Default sizes are 'small', 'medium', 'large'.
   111 	 *
   129 	 *
   112 	 *     @type array ...$0 {
   130 	 *     @type array ...$0 {
   113 	 *         @type int  $width  Image width.
   131 	 *         @type int        $width  Image width.
   114 	 *         @type int  $height Image height.
   132 	 *         @type int        $height Image height.
   115 	 *         @type bool $crop   Optional. Whether to crop the image. Default false.
   133 	 *         @type bool|array $crop   Optional. Whether to crop the image. Default false.
   116 	 *     }
   134 	 *     }
   117 	 * }
   135 	 * }
   118 	 * @return array An array of resized images metadata by size.
   136 	 * @return array An array of resized images metadata by size.
   119 	 */
   137 	 */
   120 	abstract public function multi_resize( $sizes );
   138 	abstract public function multi_resize( $sizes );
   298 		switch ( $mime_type ) {
   316 		switch ( $mime_type ) {
   299 			case 'image/webp':
   317 			case 'image/webp':
   300 				$quality = 86;
   318 				$quality = 86;
   301 				break;
   319 				break;
   302 			case 'image/jpeg':
   320 			case 'image/jpeg':
       
   321 			case 'image/avif':
   303 			default:
   322 			default:
   304 				$quality = $this->default_quality;
   323 				$quality = $this->default_quality;
   305 		}
   324 		}
   306 
   325 
   307 		return $quality;
   326 		return $quality;
   336 			// If no file specified, grab editor's current extension and mime-type.
   355 			// If no file specified, grab editor's current extension and mime-type.
   337 			$file_ext  = strtolower( pathinfo( $this->file, PATHINFO_EXTENSION ) );
   356 			$file_ext  = strtolower( pathinfo( $this->file, PATHINFO_EXTENSION ) );
   338 			$file_mime = $this->mime_type;
   357 			$file_mime = $this->mime_type;
   339 		}
   358 		}
   340 
   359 
   341 		// Check to see if specified mime-type is the same as type implied by
   360 		/*
   342 		// file extension. If so, prefer extension from file.
   361 		 * Check to see if specified mime-type is the same as type implied by
   343 		if ( ! $mime_type || ( $file_mime == $mime_type ) ) {
   362 		 * file extension. If so, prefer extension from file.
       
   363 		 */
       
   364 		if ( ! $mime_type || ( $file_mime === $mime_type ) ) {
   344 			$mime_type = $file_mime;
   365 			$mime_type = $file_mime;
   345 			$new_ext   = $file_ext;
   366 			$new_ext   = $file_ext;
   346 		}
   367 		}
   347 
   368 
   348 		/**
   369 		/**
   371 		) {
   392 		) {
   372 			$mime_type = $output_format[ $mime_type ];
   393 			$mime_type = $output_format[ $mime_type ];
   373 			$new_ext   = $this->get_extension( $mime_type );
   394 			$new_ext   = $this->get_extension( $mime_type );
   374 		}
   395 		}
   375 
   396 
   376 		// Double-check that the mime-type selected is supported by the editor.
   397 		/*
   377 		// If not, choose a default instead.
   398 		 * Double-check that the mime-type selected is supported by the editor.
       
   399 		 * If not, choose a default instead.
       
   400 		 */
   378 		if ( ! $this->supports_mime_type( $mime_type ) ) {
   401 		if ( ! $this->supports_mime_type( $mime_type ) ) {
   379 			/**
   402 			/**
   380 			 * Filters default mime type prior to getting the file extension.
   403 			 * Filters default mime type prior to getting the file extension.
   381 			 *
   404 			 *
   382 			 * @see wp_get_mime_types()
   405 			 * @see wp_get_mime_types()
   387 			 */
   410 			 */
   388 			$mime_type = apply_filters( 'image_editor_default_mime_type', $this->default_mime_type );
   411 			$mime_type = apply_filters( 'image_editor_default_mime_type', $this->default_mime_type );
   389 			$new_ext   = $this->get_extension( $mime_type );
   412 			$new_ext   = $this->get_extension( $mime_type );
   390 		}
   413 		}
   391 
   414 
   392 		// Ensure both $filename and $new_ext are not empty.
   415 		/*
   393 		// $this->get_extension() returns false on error which would effectively remove the extension
   416 		 * Ensure both $filename and $new_ext are not empty.
   394 		// from $filename. That shouldn't happen, files without extensions are not supported.
   417 		 * $this->get_extension() returns false on error which would effectively remove the extension
       
   418 		 * from $filename. That shouldn't happen, files without extensions are not supported.
       
   419 		 */
   395 		if ( $filename && $new_ext ) {
   420 		if ( $filename && $new_ext ) {
   396 			$dir = pathinfo( $filename, PATHINFO_DIRNAME );
   421 			$dir = pathinfo( $filename, PATHINFO_DIRNAME );
   397 			$ext = pathinfo( $filename, PATHINFO_EXTENSION );
   422 			$ext = pathinfo( $filename, PATHINFO_EXTENSION );
   398 
   423 
   399 			$filename = trailingslashit( $dir ) . wp_basename( $filename, ".$ext" ) . ".{$new_ext}";
   424 			$filename = trailingslashit( $dir ) . wp_basename( $filename, ".$ext" ) . ".{$new_ext}";
   401 
   426 
   402 		if ( $mime_type && ( $mime_type !== $this->mime_type ) ) {
   427 		if ( $mime_type && ( $mime_type !== $this->mime_type ) ) {
   403 			// The image will be converted when saving. Set the quality for the new mime-type if not already set.
   428 			// The image will be converted when saving. Set the quality for the new mime-type if not already set.
   404 			if ( $mime_type !== $this->output_mime_type ) {
   429 			if ( $mime_type !== $this->output_mime_type ) {
   405 				$this->output_mime_type = $mime_type;
   430 				$this->output_mime_type = $mime_type;
   406 				$this->set_quality();
       
   407 			}
   431 			}
       
   432 			$this->set_quality();
   408 		} elseif ( ! empty( $this->output_mime_type ) ) {
   433 		} elseif ( ! empty( $this->output_mime_type ) ) {
   409 			// Reset output_mime_type and quality.
   434 			// Reset output_mime_type and quality.
   410 			$this->output_mime_type = null;
   435 			$this->output_mime_type = null;
   411 			$this->set_quality();
   436 			$this->set_quality();
   412 		}
   437 		}
   499 		}
   524 		}
   500 
   525 
   501 		switch ( $orientation ) {
   526 		switch ( $orientation ) {
   502 			case 2:
   527 			case 2:
   503 				// Flip horizontally.
   528 				// Flip horizontally.
   504 				$result = $this->flip( true, false );
   529 				$result = $this->flip( false, true );
   505 				break;
   530 				break;
   506 			case 3:
   531 			case 3:
   507 				// Rotate 180 degrees or flip horizontally and vertically.
   532 				/*
   508 				// Flipping seems faster and uses less resources.
   533 				 * Rotate 180 degrees or flip horizontally and vertically.
       
   534 				 * Flipping seems faster and uses less resources.
       
   535 				 */
   509 				$result = $this->flip( true, true );
   536 				$result = $this->flip( true, true );
   510 				break;
   537 				break;
   511 			case 4:
   538 			case 4:
   512 				// Flip vertically.
   539 				// Flip vertically.
   513 				$result = $this->flip( false, true );
   540 				$result = $this->flip( true, false );
   514 				break;
   541 				break;
   515 			case 5:
   542 			case 5:
   516 				// Rotate 90 degrees counter-clockwise and flip vertically.
   543 				// Rotate 90 degrees counter-clockwise and flip vertically.
   517 				$result = $this->rotate( 90 );
   544 				$result = $this->rotate( 90 );
   518 
   545 
   519 				if ( ! is_wp_error( $result ) ) {
   546 				if ( ! is_wp_error( $result ) ) {
   520 					$result = $this->flip( false, true );
   547 					$result = $this->flip( true, false );
   521 				}
   548 				}
   522 
   549 
   523 				break;
   550 				break;
   524 			case 6:
   551 			case 6:
   525 				// Rotate 90 degrees clockwise (270 counter-clockwise).
   552 				// Rotate 90 degrees clockwise (270 counter-clockwise).
   528 			case 7:
   555 			case 7:
   529 				// Rotate 90 degrees counter-clockwise and flip horizontally.
   556 				// Rotate 90 degrees counter-clockwise and flip horizontally.
   530 				$result = $this->rotate( 90 );
   557 				$result = $this->rotate( 90 );
   531 
   558 
   532 				if ( ! is_wp_error( $result ) ) {
   559 				if ( ! is_wp_error( $result ) ) {
   533 					$result = $this->flip( true, false );
   560 					$result = $this->flip( false, true );
   534 				}
   561 				}
   535 
   562 
   536 				break;
   563 				break;
   537 			case 8:
   564 			case 8:
   538 				// Rotate 90 degrees counter-clockwise.
   565 				// Rotate 90 degrees counter-clockwise.
   626 		}
   653 		}
   627 
   654 
   628 		return wp_get_default_extension_for_mime_type( $mime_type );
   655 		return wp_get_default_extension_for_mime_type( $mime_type );
   629 	}
   656 	}
   630 }
   657 }
   631