Getting the closest named image size from an array of dimensions

Turns out, image_get_intermediate_size() was easy enough to adapt to my needs. Instead of using wp_get_attachment_metadata to get an existing image’s available sizes I use my own function to get all available image sizes (essentially the same as the function proposed here). I then simply return the name rather than the array of meta data.

It works, I need to do some more thorough testing though and may need to make some changes (not sure I actually want to return ‘thumbnail’ for sizes smaller than ‘thumbnail’ for example)…

Here is my entire function (it is a static method of a utility class):

/**
 * Return the closest named size from an array of width and height values.
 *
 * Based off of WordPress's image_get_intermediate_size()
 * If the size matches an existing size 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 return false.
 * Uses get_image_sizes() to get all available sizes.
 *
 * @param  array|string $size   Image size. Accepts an array of width and height (in that order).
 * @return false|string $data   named image size e.g. 'thumbnail'.
 */
public static function get_named_size( $size ) {

    $image_sizes = self::get_image_sizes();
    $data = array();

    // Find the best match when '$size' is an array.
    if ( is_array( $size ) ) {
        $candidates = array();

        foreach ( $image_sizes as $_size => $data ) {

            // If there's an exact match to an existing image size, short circuit.
            if ( $data['width'] == $size[0] && $data['height'] == $size[1] ) {
                $candidates[ $data['width'] * $data['height'] ] = array( $_size, $data );
                break;
            }

            // If it's not an exact match, consider larger sizes with the same aspect ratio.
            if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) {
                if ( wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] ) ) {
                    $candidates[ $data['width'] * $data['height'] ] = array( $_size, $data );
                }
            }
        }

        if ( ! empty( $candidates ) ) {
            // Sort the array by size if we have more than one candidate.
            if ( 1 < count( $candidates ) ) {
                ksort( $candidates );
            }

            $data = array_shift( $candidates );
            $data = $data[0];
        /*
         * When the size requested is smaller than the thumbnail dimensions, we
         * fall back to the thumbnail size to maintain backwards compatibility with
         * pre 4.6 versions of WordPress.
         */
        } elseif ( ! empty( $image_sizes['thumbnail'] ) && $image_sizes['thumbnail']['width'] >= $size[0] && $image_sizes['thumbnail']['width'] >= $size[1] ) {
            $data="thumbnail";
        } else {
            return false;
        }

    } elseif ( ! empty( $image_sizes[ $size ] ) ) {
        $data = $size;
    }

    // If we still don't have a match at this point, return false.
    if ( empty( $data ) ) {
        return false;
    }

    return $data;
}

Which I can use (close enough to) how I initially wanted:

$image_size = My_Utility_Class::get_named_size( array( 150, 150 ) ); // returns 'thumbnail'