Created
October 29, 2013 08:10
-
-
Save roytanck/7210727 to your computer and use it in GitHub Desktop.
Modified version of image_get_intermediate_size (WordPress, media.php) which checks for an exact match (width and height) before attempting to find a matching width OR height. This fixes the function's behavior in some cases, but a better solution is to add proper aspect handling to the function.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Retrieve the image's intermediate size (resized) path, width, and height. | |
* | |
* The $size parameter can be an array with the width and height respectively. | |
* If the size matches the 'sizes' metadata array for width and height, then it | |
* will be used. If there is no direct match, then the nearest image size larger | |
* than the specified size will be used. If nothing is found, then the function | |
* will break out and return false. | |
* | |
* The metadata 'sizes' is used for compatible sizes that can be used for the | |
* parameter $size value. | |
* | |
* The url path will be given, when the $size parameter is a string. | |
* | |
* If you are passing an array for the $size, you should consider using | |
* add_image_size() so that a cropped version is generated. It's much more | |
* efficient than having to find the closest-sized image and then having the | |
* browser scale down the image. | |
* | |
* @since 2.5.0 | |
* @see add_image_size() | |
* | |
* @param int $post_id Attachment ID for image. | |
* @param array|string $size Optional, default is 'thumbnail'. Size of image, either array or string. | |
* @return bool|array False on failure or array of file path, width, and height on success. | |
*/ | |
function image_get_intermediate_size($post_id, $size='thumbnail') { | |
if ( !is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) ) | |
return false; | |
// get the best one for a specified set of dimensions | |
if ( is_array($size) && !empty($imagedata['sizes']) ) { | |
foreach ( $imagedata['sizes'] as $_size => $data ) { | |
// already cropped to width and height; so use this size | |
if ( ( $data['width'] == $size[0] && $data['height'] == $size[1] ) ) { | |
$file = $data['file']; | |
list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); | |
return compact( 'file', 'width', 'height' ); | |
} | |
} | |
foreach ( $imagedata['sizes'] as $_size => $data ) { | |
// already cropped to width or height; so use this size | |
if ( ( $data['width'] == $size[0] && $data['height'] <= $size[1] ) || ( $data['height'] == $size[1] && $data['width'] <= $size[0] ) ) { | |
$file = $data['file']; | |
list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); | |
return compact( 'file', 'width', 'height' ); | |
} | |
// add to lookup table: area => size | |
$areas[$data['width'] * $data['height']] = $_size; | |
} | |
if ( !$size || !empty($areas) ) { | |
// find for the smallest image not smaller than the desired size | |
ksort($areas); | |
foreach ( $areas as $_size ) { | |
$data = $imagedata['sizes'][$_size]; | |
if ( $data['width'] >= $size[0] || $data['height'] >= $size[1] ) { | |
// Skip images with unexpectedly divergent aspect ratios (crops) | |
// First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop | |
$maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false ); | |
// 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 | |
if ( 'thumbnail' != $_size && ( !$maybe_cropped || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] ) || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] ) ) ) | |
continue; | |
// If we're still here, then we're going to use this size | |
$file = $data['file']; | |
list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); | |
return compact( 'file', 'width', 'height' ); | |
} | |
} | |
} | |
} | |
if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) ) | |
return false; | |
$data = $imagedata['sizes'][$size]; | |
// include the full filesystem path of the intermediate file | |
if ( empty($data['path']) && !empty($data['file']) ) { | |
$file_url = wp_get_attachment_url($post_id); | |
$data['path'] = path_join( dirname($imagedata['file']), $data['file'] ); | |
$data['url'] = path_join( dirname($file_url), $data['file'] ); | |
} | |
return $data; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment