Algorithm to resize image and maintain aspect ratio to fit iPhone

后端 未结 5 838
傲寒
傲寒 2020-12-24 04:55

I\'m creating a web service for an iPhone app to interact with.

When my client uploads images server-side, I want my php script to resize the image, whilst m

相关标签:
5条回答
  • 2020-12-24 05:43

    I think the following should give you the idea. It's not in any particular language, but rather a C-like pseudo code.

    shortSideMax = 640;
    longSideMax = 960;
    function Resize(image)
    {
        if (image.width >= image.height)
        {
            if (image.width <= longSideMax && image.height <= shortSideMax)
                return image;  // no resizing required
            wRatio = longSideMax / image.width;
            hRatio = shortSideMax / image.height;
        }
        else
        {
            if (image.height <= longSideMax && image.width <= shortSideMax)
                return image; // no resizing required
            wRatio = shortSideMax / image.width;
            hRatio = longSideMax / image.height;
        }
    
        // hRatio and wRatio now have the scaling factors for height and width.
        // You want the smallest of the two to ensure that the resulting image
        // fits in the desired frame and maintains the aspect ratio.
        resizeRatio = Min(wRatio, hRatio);
    
        newHeight = image.Height * resizeRatio;
        newWidth = image.Width * resizeRatio;
    
        // Now call function to resize original image to [newWidth, newHeight]
        // and return the result.
    }
    

    The efficiency of this code, or what you have, won't be an issue. The time it takes to actually resize the image will dwarf the time it takes to do a couple of comparisons, two divides, and two multiplies.

    Is this a "more mathematical" way to do it? I suppose, in that it collapses your four cases into two. But the approach is essentially the same.

    0 讨论(0)
  • 2020-12-24 05:43

    Below, the simplest way I know to keep proportions. Hope it helps.

    Javascript

    function resize(width, height, maxWidth, maxHeight) {
        var ratio = Math.min(maxWidth / width, maxHeight / height);
        var newWidth = ratio * width;
        var newHeight = ratio * height;
    
        console.log(newWidth + ' ' + newHeight); // Test
    
        // Process resizing...
    }
    
    resize(1280, 1024, 600, 300);
    

    PHP

    function resize($width, $height, $maxWidth, $maxHeight) {
        $ratio = min(array($maxWidth / $width, $maxHeight / $height));
        $newWidth = $ratio * $width;
        $newHeight = $ratio * $height;
    
        echo $newWidth . ' ' . $newHeight; // Test
    
        // Process resizing...
    }
    
    resize(1600, 1280, 150, 150);
    
    0 讨论(0)
  • 2020-12-24 05:46

    Maybe a slightly shorter routine would be:

    // Calculate resize ratios for resizing 
    float ratioW = targetWidth / oldWidth; 
    float ratioH = targetHeight / oldHeight;
    
    // smaller ratio will ensure that the image fits in the view
    float ratio = ratioW < ratioH?ratioW:ratioH;
    
    newWidth = oldWidth*ratio;
    newHeight = oldHeight*ratio;
    

    Obviously if the ratio is > 1, then it's enlarging, if < 1 then it's shrinking.

    0 讨论(0)
  • 2020-12-24 05:54

    Any one coming to this page from Google looking for ASPECT FILL not ASPECT FIT, it is simply a matter of switching the ratio selection code i.e:

    Jim's answer:

    resizeRatio = Min(wRatio, hRatio); //Aspect Fit
    

    becomes

    resizeRatio = Max(wRatio, hRatio); //Aspect Fill
    

    DevProd's answer:

    float ratio = ratioW < ratioH?ratioW:ratioH; //Aspect Fit
    

    becomes

    float ratio = ratioW > ratioH?ratioW:ratioH; //Aspect Fill
    
    0 讨论(0)
  • 2020-12-24 05:56

    Similar to DevProd's answer, but I struggled to follow it myself because of the naming convention. Hopefully this is a little clearer:

    How do I best-fit some media (a photo) inside a container?

    //Define media size and container size
    int mediaWidth = 600;
    int mediaHeight = 600;
    int containerWidth = 1024;
    int containerHeight= 768;
    
    //Calculate best fit (whichever dimension has a smaller 'fit')
    float wFits   = containerWidth  / mediaWidth;
    float hFits   = containerHeight / mediaHeight;
    float minFits = wFits > hFits ? hFits : wFits;
    
    //The new size of the media, best-fit'ing inside the container
    int width  = (int) (mediaWidth*minFits);
    int height = (int) (mediaHeight*minFits);
    
    0 讨论(0)
提交回复
热议问题