72

我有一个源矩形和一个目标矩形。我需要找到源可以缩放到的最大比例,同时适合目标矩形并保持其原始纵横比

谷歌找到了一种方法,但我不确定它是否适用于所有情况。这是我自制的解决方案:

  • 计算每个矩形的高度/宽度。这给出了对角线的斜率msrcmdest
  • 如果msrc < mdst,缩放源宽度以适应目标宽度(并按相同比例缩放高度)
  • 否则,缩放源高度以适应目标高度(并按相同比例缩放宽度)

寻找其他可能的解决方案来解决这个问题。我什至不确定我的算法是否适用于所有情况!

4

5 回答 5

143
scale = min(dst.width/src.width, dst.height/src.height)

这是你的方法,但写得更干净。

于 2009-09-03T14:50:34.423 回答
13

另一种选择可能是缩放到最大宽度,然后检查缩放高度是否大于最大允许高度,如果是,则按高度缩放(反之亦然):

scale = (dst.width / src.width);
if (src.height * scale > dst.height)
 scale = dst.height / src.height;

我认为这个解决方案更短、更快、更容易理解。

于 2009-09-03T12:18:48.187 回答
2
  1. 计算出和中的较小destWidth / srcWidthdestHeight / srcHeight
  2. 按比例缩放

编辑它当然与您的方法相同,只是移动了公式的各个部分。我的观点是,这在语义上更清晰,但仅此而已 - 一种观点。

于 2009-09-03T12:14:46.227 回答
1

如果所有维度都不为零,我将使用以下代码(基本上与您的代码匹配)。

scaleFactor = (outerWidth / outerHeight > innerWidth / innerHeight) 
    ? outerHeight / innerHeight
    : outerWidth / innerWidth

如果需要,这也可以修改为允许任何维度为零。

于 2009-09-03T12:41:59.357 回答
0

当 sourceWidth 或 sourceHeight 变为零时,其他答案存在产生除以零异常的风险。为了防止这种情况,我们应该将比较重写为数学上等价的多重表达式。此外,还有额外的边缘条件来捕捉无限规模的场景。

除了有比例,我真的很想要目标矩形的尺寸,所以,这里我将提供比例计算和目标矩形计算。

由于无限边缘条件,我认为目标矩形将更加健壮/有用:

    if (sourceWidth == 0 && sourceHeight == 0) {
        // scale = Infinity;
        outputWidth = 0;
        outputHeight = 0;
        outputX = destWidth / 2;
        outputY = destHeight / 2;
    } else if (destWidth * sourceHeight > destHeight * sourceWidth) {
        scale = destHeight / sourceHeight;
        outputWidth = sourceWidth * destHeight / sourceHeight;
        outputHeight = destHeight;
        outputX = (destWidth - outputWidth) / 2;
        outputY = 0;
    } else {
        scale = destWidth / sourceWidth;
        outputWidth = destWidth;
        outputHeight = sourceHeight * destWidth / sourceWidth;
        outputX = 0;
        outputY = (destHeight - outputHeight) / 2;
    }
于 2018-06-15T04:16:14.447 回答