Skip to content

Instantly share code, notes, and snippets.

@roytanck
Created October 29, 2013 14:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roytanck/7216231 to your computer and use it in GitHub Desktop.
Save roytanck/7216231 to your computer and use it in GitHub Desktop.
Possible approach to handling aspect ration differences when finding the best match for a requested image resolution in WordPress's image_get_intermediate_size function in media.php.
/**
* 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 or 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' );
}
// calculate difference in aspect and resolution betweenn current image and requested resolution
// values os zero are exact matches, higher numbers are worse
$aspect_proximity = abs( ( $data['width'] / $data['height'] ) - ( $size[0] / $size[1] ) );
$resolution_proximity = ( abs( $size[0] - $data['width'] ) + abs( $size[1] - $data['height'] ) ) / ( $size[0] + $size[1] );
// add to lookup array
$match_proximity = ( $aspect_proximity + $resolution_proximity ) * 100;
$matches[ $match_proximity ] = $_size;
}
// sort the results, so the best match becomes the first element in the array
ksort( $areas );
// return the best match
$data = $imagedata['sizes'][ $areas[0] ];
$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