调整图像大小和保持宽高比以适合iPhone的算法

时间:2011-10-23 00:53:50

标签: php algorithm image resize aspect-ratio

我正在为iPhone应用程序创建一个与之交互的Web服务。

当我的客户端上传服务器端的图像时,我希望我的php脚本调整图像大小,同时保持宽高比,以便它适合iPhone屏幕。 (即最长边是<= 960并且最短<= 640

我在JS中创建了一个模型,只是因为我发现它更容易快速完成。

我很确定,虽然我可能错了,但这并不是最有效的方式。有人可以用更好的逻辑(尤其是开头的那个)或更接近这个的数学方法来纠正我吗?

var w = 960, h = 960, new_w, new_h;
if (w >= h && w > 960 || h >= w && h > 960 || w >= h && h > 640 || h >= w && w > 640) {
    if (w > h) {
        if (w>960) {
            new_w = 960;
            new_h = h*(new_w/w);
        }
        if (h>640) {
            new_h = 640;
            new_w = w*(new_h/h);
        }
    }
    else {
        if (h>960) {
            new_h = 960;
            new_w = w*(new_h/h);
        }
        if (w>640) {
            new_w = 640;
            new_h = h*(new_w/w);
        }
    }
}

5 个答案:

答案 0 :(得分:41)

可能会稍微缩短一下例程:

// 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;

显然,如果比率> 1,然后它正在扩大,如果&lt; 1然后它在萎缩。

答案 1 :(得分:24)

我认为以下内容可以为您提供这个想法。它不是任何特定的语言,而是类似C的伪代码。

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.
}

此代码的效率或您拥有的代码不会成为问题。实际调整图像大小所需的时间将使进行几次比较,两次除法和两次乘法所花费的时间相形见绌。

这是一种“更加数学化”的方式吗?我想,因为它将你的四个案件分成两个。但方法基本相同。

答案 2 :(得分:7)

下面,我知道保持比例的最简单方法。希望它有所帮助。

<强>的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);

答案 3 :(得分:3)

任何人都会从Google进入此页面寻找 ASPECT FILL 而非 ASPECT FIT ,这只是转换比率选择代码的问题,即:

吉姆的回答:

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

变为

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

DevProd的回答:

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

变为

float ratio = ratioW > ratioH?ratioW:ratioH; //Aspect Fill

答案 4 :(得分:0)

与DevProd的答案类似,但由于命名惯例,我自己也很难跟踪它。希望这更清楚一点:

  

如何在容器内最适合某些媒体(照片)?

//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);
相关问题