【问题标题】:Algorithm to resize image and maintain aspect ratio to fit iPhone调整图像大小并保持宽高比以适合 iPhone 的算法
【发布时间】:2011-12-13 09:37:18
【问题描述】:

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

当我的客户端在服务器端上传图片时,我希望我的 php 脚本调整图片的大小,同时保持宽高比,使其适合 iPhone 屏幕。 (即最长边为

我用 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);
        }
    }
}

【问题讨论】:

  • 唯一的问题是您在检查 w>960 后立即采取行动,并假设 new_h=h*(new_w/w)

标签: php algorithm image resize aspect-ratio


【解决方案1】:

类似于 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);

【讨论】:

    【解决方案2】:

    任何人从谷歌来到这个页面寻找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
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 这比其他答案更简单。使用Math.min()“适合”并使用Math.max()“填充”。
      【解决方案4】:

      也许一个稍微短一点的例程是:

      // 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,则放大,如果

      【讨论】:

      • 我只想指出,在方面适合和方面填充之间进行更改非常简单。对于方面填充,只需填写标志:float ratio = ratioW &gt; ratioH ? ratioW : ratioH;
      【解决方案5】:

      我认为以下内容应该会给您一些想法。它不是任何特定语言,而是类似 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.
      }
      

      这段代码的效率,或者你所拥有的,都不是问题。实际调整图像大小所需的时间将使进行几次比较、两次除法和两次乘法所需的时间相形见绌。

      这是一种“更数学”的方式吗?我想,因为它把你的四个箱子一分为二。但方法基本相同。

      【讨论】:

      • 我有几乎完全相同的算法,但很高兴看到其他人对这个问题的解决方案 - 并且注意到实际对图像执行调整大小操作将使算法的效率提高争论点。
      • 当图像的高度为 800 且宽度为 600 而 shortsidemax 为 275(垂直)而 longsidemax 为 480(水平)时,此算法对我不起作用。
      • @ManishJain:然后,您应该发布一个问题,展示您尝试过的内容以及获得的结果。请务必链接此答案并说明它不起作用。
      猜你喜欢
      • 2013-02-01
      • 2023-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 2015-05-22
      相关资源
      最近更新 更多