Changeset 46202
- Timestamp:
- 09/20/2019 06:20:26 PM (5 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/image.php
r46076 r46202 160 160 161 161 /** 162 * Updates the attached file and image meta data when the original image was edited. 163 * 164 * @since 5.3.0 165 * @access private 166 * 167 * @param array $saved_data The data retirned from WP_Image_Editor after successfully saving an image. 168 * @param string $original_file Path to the original file. 169 * @param array $image_meta The image meta data. 170 * @param int $attachment_id The attachment post ID. 171 * @return array The updated image meta data. 172 */ 173 function _wp_image_meta_replace_original( $saved_data, $original_file, $image_meta, $attachment_id ) { 174 $new_file = $saved_data['path']; 175 176 // Update the attached file meta. 177 update_attached_file( $attachment_id, $new_file ); 178 179 // Width and height of the new image. 180 $image_meta['width'] = $saved_data['width']; 181 $image_meta['height'] = $saved_data['height']; 182 183 // Make the file path relative to the upload dir. 184 $image_meta['file'] = _wp_relative_upload_path( $new_file ); 185 186 // Store the original image file name in image_meta. 187 $image_meta['original_image'] = wp_basename( $original_file ); 188 189 return $image_meta; 190 } 191 192 /** 162 193 * Creates image sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata. 163 194 * … … 223 254 // Resize the image 224 255 $resized = $editor->resize( $threshold, $threshold ); 256 $rotated = null; 257 258 // If there is EXIF data, rotate according to EXIF Orientation. 259 if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) { 260 $resized = $editor->maybe_exif_rotate(); 261 $rotated = $resized; 262 } 225 263 226 264 if ( ! is_wp_error( $resized ) ) { 227 // TODO: EXIF rotate here. 228 // By default the editor will append `{width}x{height}` to the file name of the resized image. 229 // Better to append the threshold size instead so the image file name would be like "my-image-2560.jpg" 230 // and not look like a "regular" sub-size. 265 // Append the threshold size to the image file name. It will look like "my-image-2560.jpg". 231 266 // This doesn't affect the sub-sizes names as they are generated from the original image (for best quality). 232 267 $saved = $editor->save( $editor->generate_filename( $threshold ) ); 233 268 234 269 if ( ! is_wp_error( $saved ) ) { 235 $new_file = $saved['path']; 236 237 // Update the attached file meta. 238 update_attached_file( $attachment_id, $new_file ); 239 240 // Width and height of the new image. 241 $image_meta['width'] = $saved['width']; 242 $image_meta['height'] = $saved['height']; 243 244 // Make the file path relative to the upload dir. 245 $image_meta['file'] = _wp_relative_upload_path( $new_file ); 246 247 // Store the original image file name in image_meta. 248 $image_meta['original_image'] = wp_basename( $file ); 270 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id ); 271 272 // If the image was rotated update the stored EXIF data. 273 if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) { 274 $image_meta['image_meta']['orientation'] = 1; 275 } 276 } else { 277 // TODO: handle errors. 278 } 279 } else { 280 // TODO: handle errors. 281 } 282 } elseif ( ! empty( $exif_meta['orientation'] ) && (int) $exif_meta['orientation'] !== 1 ) { 283 // Rotate the whole original image if there is EXIF data and "orientation" is not 1. 284 285 $editor = wp_get_image_editor( $file ); 286 287 if ( is_wp_error( $editor ) ) { 288 // This image cannot be edited. 289 return $image_meta; 290 } 291 292 // Rotate the image 293 $rotated = $editor->maybe_exif_rotate(); 294 295 if ( true === $rotated ) { 296 // Append `-rotated` to the image file name. 297 $saved = $editor->save( $editor->generate_filename( 'rotated' ) ); 298 299 if ( ! is_wp_error( $saved ) ) { 300 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id ); 301 302 // Update the stored EXIF data. 303 if ( ! empty( $image_meta['image_meta']['orientation'] ) ) { 304 $image_meta['image_meta']['orientation'] = 1; 305 } 306 } else { 307 // TODO: handle errors. 249 308 } 250 309 } … … 326 385 // The image cannot be edited. 327 386 return $image_meta; 387 } 388 389 // If stored EXIF data exists, rotate the source image before creating sub-sizes. 390 if ( ! empty( $image_meta['image_meta'] ) ) { 391 $rotated = $editor->maybe_exif_rotate(); 392 393 if ( is_wp_error( $rotated ) ) { 394 // TODO: handle errors. 395 } 328 396 } 329 397 -
trunk/src/wp-includes/class-wp-image-editor-imagick.php
r46088 r46202 567 567 $this->image->rotateImage( new ImagickPixel( 'none' ), 360 - $angle ); 568 568 569 // Normalise E xiforientation data so that display is consistent across devices.569 // Normalise EXIF orientation data so that display is consistent across devices. 570 570 if ( is_callable( array( $this->image, 'setImageOrientation' ) ) && defined( 'Imagick::ORIENTATION_TOPLEFT' ) ) { 571 571 $this->image->setImageOrientation( Imagick::ORIENTATION_TOPLEFT ); … … 603 603 $this->image->flopImage(); 604 604 } 605 606 // Normalise EXIF orientation data so that display is consistent across devices. 607 if ( is_callable( array( $this->image, 'setImageOrientation' ) ) && defined( 'Imagick::ORIENTATION_TOPLEFT' ) ) { 608 $this->image->setImageOrientation( Imagick::ORIENTATION_TOPLEFT ); 609 } 605 610 } catch ( Exception $e ) { 606 611 return new WP_Error( 'image_flip_error', $e->getMessage() ); 607 612 } 613 608 614 return true; 615 } 616 617 /** 618 * Check if a JPEG image has EXIF Orientation tag and rotate it if needed. 619 * 620 * As ImageMagick copies the EXIF data to the flipped/rotated image, proceed only 621 * if EXIF Orientation can be reset afterwards. 622 * 623 * @since 5.3.0 624 * 625 * @return bool|WP_Error True if the image was rotated. False if no EXIF data or if the image doesn't need rotation. 626 * WP_Error if error while rotating. 627 */ 628 public function maybe_exif_rotate() { 629 if ( is_callable( array( $this->image, 'setImageOrientation' ) ) && defined( 'Imagick::ORIENTATION_TOPLEFT' ) ) { 630 return parent::maybe_exif_rotate(); 631 } else { 632 return new WP_Error( 'write_exif_error', __( 'The image cannot be rotated because the embedded meta data cannot be updated.' ) ); 633 } 609 634 } 610 635 -
trunk/src/wp-includes/class-wp-image-editor.php
r45590 r46202 386 386 387 387 /** 388 * Check if a JPEG image has EXIF Orientation tag and rotate it if needed. 389 * 390 * @since 5.3.0 391 * 392 * @return bool|WP_Error True if the image was rotated. False if not rotated (no EXIF data or the image doesn't need to be rotated). 393 * WP_Error if error while rotating. 394 */ 395 public function maybe_exif_rotate() { 396 $orientation = null; 397 398 if ( is_callable( 'exif_read_data' ) && 'image/jpeg' === $this->mime_type ) { 399 $exif_data = @exif_read_data( $this->file ); 400 401 if ( ! empty( $exif_data['Orientation'] ) ) { 402 $orientation = (int) $exif_data['Orientation']; 403 } 404 } 405 406 /** 407 * Filters the `$orientation` value to correct it before rotating or to prevemnt rotating the image. 408 * 409 * @since 5.3.0 410 * 411 * @param int $orientation EXIF Orientation value as retrieved from the image file. 412 * @param string $file Path to the image file. 413 */ 414 $orientation = apply_filters( 'wp_image_maybe_exif_rotate', $orientation, $this->file ); 415 416 if ( ! $orientation || $orientation === 1 ) { 417 return false; 418 } 419 420 switch ( $orientation ) { 421 case 2: 422 // Flip horizontally. 423 $result = $this->flip( true, false ); 424 break; 425 case 3: 426 // Rotate 180 degrees or flip horizontally and vertically. 427 // Flipping seems faster/uses less resources. 428 $result = $this->flip( true, true ); 429 break; 430 case 4: 431 // Flip vertically. 432 $result = $this->flip( false, true ); 433 break; 434 case 5: 435 // Rotate 90 degrees counter-clockwise and flip vertically. 436 $result = $this->rotate( 90 ); 437 438 if ( ! is_wp_error( $result ) ) { 439 $result = $this->flip( false, true ); 440 } 441 442 break; 443 case 6: 444 // Rotate 90 degrees clockwise (270 counter-clockwise). 445 $result = $this->rotate( 270 ); 446 break; 447 case 7: 448 // Rotate 90 degrees counter-clockwise and flip horizontally. 449 $result = $this->rotate( 90 ); 450 451 if ( ! is_wp_error( $result ) ) { 452 $result = $this->flip( true, false ); 453 } 454 455 break; 456 case 8: 457 // Rotate 90 degrees counter-clockwise. 458 $result = $this->rotate( 90 ); 459 break; 460 } 461 462 return $result; 463 } 464 465 /** 388 466 * Either calls editor's save function or handles file as a stream. 389 467 *
Note: See TracChangeset
for help on using the changeset viewer.