Finding closest larger resolution with nearest aspect ratio in an array of resolutions

arrays, image, image-resizing, php, resolution

Solution

Try this

echo getClosestRes('500x960');
echo '<br /> try too large to match: '.getClosestRes('50000x960');

function getClosestRes($res){
    $screens = array(
        'landscape'=>array(
            '640x480',
            '1200x800'
        ),
        'portrait'=>array(
            '480x640',
            '480x800',
            '640x960',
            '800x1280',
            '1536x2048'
        )
    );

    list($x,$y)=explode('x',$res);
    $use=($x>$y?'landscape':'portrait');

    // if exact match exists return original
    if (array_search($res, $screens[$use])) return $res; 

    foreach ($screens[$use] as $screen){
        $s=explode('x',$screen);
        if ($s[0]>=$x && $s[1]>=$y) return $screen;
    }
    // just return largest if it gets this far.
    return $screen; // last one set to $screen is largest
}

Problem

I have an array: ``` $resolutions = array( '480x640', '480x800', '640x480', '640x960', '800x1280', '2048x1536' ); ``` I want to retrieve closest larger value with the nearest aspect ratio (same orientation). So, in case of `$needle = '768x1280'` - `800x1280`. And, in case of `$needle = '320x240'` - `640x480`. While the closest here is `480x640` it shouldn't be matched, because its aspect ratio differs too much. So on, and so forth. Purpose: I have a set of images with resolutions as specified in `$resolutions`. Those images are going to be used for smartphone wallpapers. With JavaScript, I am sending over a request with `screen.width` and `screen.height` to determine `$needle`. On the server side, I am going to fetch the closest larger value of the given resolution, scale it down to fit the whole screen while preserving aspect ratio, and if something overlaps the dimensions, crop it to perfectly fit the screen. Problem: While everything is pretty simple with scaling and cropping, I cannot think of a way to find out the closest larger value, to load the reference image. Hints: In case it helps, `$resolutions` and `$needle` can be in a different format, ie.: `array('width' => x, 'height' => y)`. Tries: I tried to experiment with levenshtein distance: http://codepad.viper-7.com/e8JGOw Apparently, it worked only for `768x1280` and resulted `800x1280`. For `320x240` it resulted in `480x640` but that does not fit this time.

Original source