Finding closest larger resolution with nearest asp

2019-05-04 19:49发布

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.

7条回答
再贱就再见
2楼-- · 2019-05-04 20:52

Okay, I have it. I've written a function that returns the lowest suitable resolution, and accounts for nonstandard resolutions as well.

    <?php
    //some obscure resolution, for illustrative purposes
    $theirResolution = '530x700'; 
    $resolutions = array(
        '480x640',
        '480x800',
        '640x480',
        '640x960',
        '800x1280',
        '2048x1536'
    );

    function findSmallestResolution($theirResolution,$resolutions){
        $temp = explode('x',$theirResolution);
        //Isolate their display's X dimension
        $theirResolutionX = intval($temp[1]);
        foreach($resolutions as $key => $value){
            $temp = explode('x',$value);
            //if the current resolution is bigger than or equal to theirs in the X dimension, then it's a possibility.
            if($theirResolutionX <= intval($temp[1])){
                $possibleResolutionsX[] = $value;
            }
        }
        //Now we'll filter our $possibleResolutions in the Y dimension.
        $temp = explode('x',$theirResolution);
        //Isolate their display's Y dimension
        $theirResolutionY = intval($temp[0]);
        foreach($possibleResolutionsX as $key => $value){
            $temp = explode('x',$value);
            //if the current resolution is bigger than or equal to theirs in the X dimension, then it's a possibility.
            if($theirResolutionY <= intval($temp[0])){
                $possibleResolutionsXY[] = $value;
            }
        }
        //at this point, $possibleResolutionsXY has all of our entries that are big enough. Now to find the smallest among them.
        foreach($possibleResolutionsXY as $key => $value){
            $temp = explode('x', $value);
            //since we didn't specify how standard our app's possible resolutions are, I'll have to measure the smallest in terms of total dots and not simply X and Y.
            $dotCount[] = intval($temp[0]) * intval($temp[1]);
        }
        //find our resolution with the least dots from the ones that still fit the user's.
        foreach($dotCount as $key => $value){
            if($value == min($dotCount)){
                $minkey = $key;
            }
        }
        //use the key from dotCount to find its corresponding resolution from possibleResolutionsXY.
        return $possibleResolutionsXY[$minkey];
    }


    findSmallestResolution($theirResolution,$resolutions);
    // returns '640x960'.


    ?>
查看更多
登录 后发表回答