Changeset 38086
- Timestamp:
- 07/18/2016 02:13:45 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/media.php
r38052 r38086 593 593 594 594 /** 595 * Helper function to test if aspect ratios for two images match. 596 * 597 * @since 4.6.0 598 * 599 * @param int $source_width Width of the first image in pixels. 600 * @param int $source_height Height of the first image in pixels. 601 * @param int $target_width Width of the second image in pixels. 602 * @param int $target_height Height of the second image in pixels. 603 * @return bool True if aspect ratios match within 1px. False if not. 604 */ 605 function wp_image_matches_ratio( $source_width, $source_height, $target_width, $target_height ) { 606 /* 607 * To test for varying crops, we constrain the dimensions of the larger image 608 * to the dimensions of the smaller image and see if they match. 609 */ 610 if ( $source_width > $target_width ) { 611 $constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width ); 612 $expected_size = array( $target_width, $target_height ); 613 } else { 614 $constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width ); 615 $expected_size = array( $source_width, $source_height ); 616 } 617 618 // If the image dimensions are within 1px of the expected size, we consider it a match. 619 $matched = ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ); 620 621 return $matched; 622 } 623 624 /** 595 625 * Retrieves the image's intermediate size (resized) path, width, and height. 596 626 * … … 624 654 * @type int $width Width of image 625 655 * @type int $height Height of image 626 * @type string $path Optional. Image's absolute filesystem path. Only returned if registered 627 * size is passed to `$size` parameter. 628 * @type string $url Optional. Image's URL. Only returned if registered size is passed to `$size` 629 * parameter. 656 * @type string $path Image's absolute filesystem path. 657 * @type string $url Image's URL. 630 658 * } 631 659 */ 632 660 function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { 633 if ( ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) )661 if ( ! $size || ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) || empty( $imagedata['sizes'] ) ) { 634 662 return false; 635 636 // get the best one for a specified set of dimensions 637 if ( is_array($size) && !empty($imagedata['sizes']) ) { 663 } 664 665 $data = array(); 666 667 // Find the best match when '$size' is an array. 668 if ( is_array( $size ) ) { 638 669 $candidates = array(); 639 670 … … 641 672 // If there's an exact match to an existing image size, short circuit. 642 673 if ( $data['width'] == $size[0] && $data['height'] == $size[1] ) { 643 list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); 644 645 /** This filter is documented in wp-includes/media.php */ 646 return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); 674 $candidates[ $data['width'] * $data['height'] ] = $data; 675 break; 647 676 } 648 // If it's not an exact match but it's at least the dimensions requested. 677 678 // If it's not an exact match, consider larger sizes with the same aspect ratio. 649 679 if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) { 650 $candidates[ $data['width'] * $data['height'] ] = $_size; 680 // If '0' is passed to either size, we test ratios against the original file. 681 if ( 0 === $size[0] || 0 === $size[1] ) { 682 $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $imagedata['width'], $imagedata['height'] ); 683 } else { 684 $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] ); 685 } 686 687 if ( $same_ratio ) { 688 $candidates[ $data['width'] * $data['height'] ] = $data; 689 } 651 690 } 652 691 } 653 692 654 693 if ( ! empty( $candidates ) ) { 655 // find for the smallest image not smaller than the desired size 656 ksort( $candidates ); 657 foreach ( $candidates as $_size ) { 658 $data = $imagedata['sizes'][$_size]; 659 660 // Skip images with unexpectedly divergent aspect ratios (crops) 661 // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop 662 $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false ); 663 // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size 664 if ( 'thumbnail' != $_size && 665 ( ! $maybe_cropped 666 || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] ) 667 || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] ) 668 ) ) { 669 continue; 670 } 671 // If we're still here, then we're going to use this size. 672 list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); 673 674 /** This filter is documented in wp-includes/media.php */ 675 return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); 694 // Sort the array by size if we have more than one candidate. 695 if ( 1 < count( $candidates ) ) { 696 ksort( $candidates ); 676 697 } 677 } 678 } 679 680 if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) ) 698 699 $data = array_shift( $candidates ); 700 /* 701 * When the size requested is smaller than the thumbnail dimensions, we 702 * fall back to the thumbnail size to maintain backwards compatibility with 703 * pre 4.6 versions of WordPress. 704 */ 705 } elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) { 706 $data = $imagedata['sizes']['thumbnail']; 707 } else { 708 return false; 709 } 710 711 // Constrain the width and height attributes to the requested values. 712 list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); 713 714 } elseif ( ! empty( $imagedata['sizes'][ $size ] ) ) { 715 $data = $imagedata['sizes'][ $size ]; 716 } 717 718 // If we still don't have a match at this point, return false. 719 if ( empty( $data ) ) { 681 720 return false; 682 683 $data = $imagedata['sizes'][$size]; 721 } 722 684 723 // include the full filesystem path of the intermediate file 685 724 if ( empty($data['path']) && !empty($data['file']) ) { … … 1093 1132 } 1094 1133 1095 /**1096 * To check for varying crops, we calculate the expected size of the smaller1097 * image if the larger were constrained by the width of the smaller and then1098 * see if it matches what we're expecting.1099 */1100 if ( $image_width > $image['width'] ) {1101 $constrained_size = wp_constrain_dimensions( $image_width, $image_height, $image['width'] );1102 $expected_size = array( $image['width'], $image['height'] );1103 } else {1104 $constrained_size = wp_constrain_dimensions( $image['width'], $image['height'], $image_width );1105 $expected_size = array( $image_width, $image_height );1106 }1107 1108 1134 // If the image dimensions are within 1px of the expected size, use it. 1109 if ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1) {1135 if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) { 1110 1136 // Add the URL, descriptor, and value to the sources array to be returned. 1111 1137 $source = array( -
trunk/tests/phpunit/tests/image/intermediate_size.php
r37328 r38086 225 225 $this->assertTrue( strpos( $image['file'], $width . 'x' . $height ) > 0 ); 226 226 } 227 228 /** 229 * @ticket 34384 230 */ 231 public function test_get_intermediate_size_with_small_size_array() { 232 // Add a hard cropped size that matches the aspect ratio we're going to test. 233 add_image_size( 'test-size', 200, 100, true ); 234 235 $file = DIR_TESTDATA . '/images/waffles.jpg'; 236 $id = $this->_make_attachment( $file, 0 ); 237 238 // Request a size by array that doesn't exist and is smaller than the 'thumbnail' 239 $image = image_get_intermediate_size( $id, array( 50, 25 ) ); 240 241 // We should get the 'test-size' file and not the thumbnail. 242 $this->assertTrue( strpos( $image['file'], '200x100' ) > 0 ); 243 } 244 245 /** 246 * @ticket 34384 247 */ 248 public function test_get_intermediate_size_with_small_size_array_fallback() { 249 $file = DIR_TESTDATA . '/images/waffles.jpg'; 250 $id = $this->_make_attachment( $file, 0 ); 251 252 $original = wp_get_attachment_metadata( $id ); 253 $thumbnail_file = $original['sizes']['thumbnail']['file']; 254 255 // Request a size by array that doesn't exist and is smaller than the 'thumbnail' 256 $image = image_get_intermediate_size( $id, array( 50, 25 ) ); 257 258 // We should get the 'thumbnail' file as a fallback. 259 $this->assertSame( $image['file'], $thumbnail_file ); 260 } 227 261 }
Note: See TracChangeset
for help on using the changeset viewer.