缩放图像以最佳地适合视口

时间:2014-07-28 02:38:54

标签: javascript image math

假设我有一个任意大小的视口(例如,浏览器窗口)。我希望以最大化分辨率的方式缩放任意宽高比和分辨率的图像以适合此视口内部。

我很难让代码在图片太高太宽的情况下工作。我可以使用什么等式来确定是否应该按宽度或高度缩放此任意图像?

以下是我使用的代码:

var aspectRatio = imageWidth / imageHeight;
if(tooWide && tooTall)
{
    // Figure out if it's better to scale on height or width by 
    if((imageWidth - viewporthWidth) > (imageHeight - viewporthHeight))
    {
        adaptedWidth = (1.0 - padding) * viewporthWidth;
        adaptedHeight = adaptedWidth / aspectRatio;
    }
    else
    {
        adaptedHeight = (1.0 - padding) * viewporthHeight;
        adaptedWidth = adaptedHeight * aspectRatio;
    }
}
else if(tooWide)
{
    adaptedWidth = (1.0 - padding) * viewporthWidth;
    adaptedHeight = adaptedWidth / aspectRatio;
}
else if(tooTall)
{
    adaptedHeight = (1.0 - padding) * viewporthHeight;
    adaptedWidth = adaptedHeight * aspectRatio;
}
else
{
    adaptedWidth = imageWidth;
    adaptedHeight = imageHeight;
}

我有一些特定尺寸的图像根本没有缩放的情况。例如,当我的视口大小为1492 x 855时,3000 x 1997图像的大小调整为1342 x 893.宽高比是正确的,但高度错误。这意味着嵌套if语句的条件是错误的(实际上,它的计算结果为1003> 1104,这暗示我们应该按高度缩放。

我认为这意味着用于缩放图像的方程式不足。

旁注:此代码是用于缩放图片的JavaScript(使用浏览器通过图片元素上的widthheight属性进行原生缩放)。在上面的代码中,padding是一个百分比,它会在图像周围创建最小量的填充(因此它不会占用整个视口)。我在代码中包含了这个,因为默认填充是0.10,这会影响我提到的数字。

2 个答案:

答案 0 :(得分:2)

您应该比较图像与视口的比率,而不是绝对差异。

这些方面的东西:

if((imageWidth / viewporthWidth) > (imageHeight / viewporthHeight))

这基本上会比较差异百分比而不是绝对差异。这很重要,因为缩放图像时,图像会减少百分比,而不是宽度和高度的绝对量。

修改

您可以在此处看到,这是您的代码示例:

http://jsfiddle.net/X2Yq6/1

使用更新的代码:

http://jsfiddle.net/X2Yq6/

在此示例中,宽度的绝对差异较大,但高度的百分比差异较大。旧代码根据宽度(不正确)进行缩放,新代码按高度进行缩放。

答案 1 :(得分:0)

我的最终答案:

var aspectRatio = imageWidth / imageHeight;
var viewportRatio = viewportWidth / viewportHeight;
var adaptedHeight = imageHeight;
var adaptedWidth  = imageWidth;


if (viewportRatio > aspectRatio) // scale by width or height?
{   adaptedHeight *= viewportWidth / imageWidth;
    adaptedWidth  *= viewportWidth / imageWidth;
}
else
{   adaptedHeight *= viewportHeight / imageHeight;
    adaptedWidth  *= viewportHeight / imageHeight;
}