如何按比例调整图像大小/保持纵横比?

Posted

技术标签:

【中文标题】如何按比例调整图像大小/保持纵横比?【英文标题】:How to resize images proportionally / keeping the aspect ratio? 【发布时间】:2011-04-27 16:13:17 【问题描述】:

我有尺寸很大的图像,我想用 jQuery 缩小它们,同时保持比例受到限制,即相同的纵横比。

谁能给我一些代码,或者解释一下逻辑?

【问题讨论】:

你能详细说明为什么必须使用 jQuery 吗?有一个纯 CSS 的解决方案(参见 my answer):将其 max-widthmax-height 设置为 100% 以防万一有人不知道,如果您只设置图像的一个维度(宽度或高度),它会按比例调整大小。自网络诞生之日起,情况就一直如此。例如:<img src='image.jpg' width=200> 另外,您可以考虑使用slimmage.js 之类的东西来节省带宽和移动设备内存。 【参考方案1】:

看看http://ericjuden.com/2009/07/jquery-image-resize/的这段代码

$(document).ready(function() 
    $('.story-small img').each(function() 
        var maxWidth = 100; // Max width for the image
        var maxHeight = 100;    // Max height for the image
        var ratio = 0;  // Used for aspect ratio
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        // Check if the current width is larger than the max
        if(width > maxWidth)
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio);  // Scale height based on ratio
            height = height * ratio;    // Reset height to match scaled image
            width = width * ratio;    // Reset width to match scaled image
        

        // Check if current height is larger than max
        if(height > maxHeight)
            ratio = maxHeight / height; // get ratio for scaling image
            $(this).css("height", maxHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
            width = width * ratio;    // Reset width to match scaled image
            height = height * ratio;    // Reset height to match scaled image
        
    );
);

【讨论】:

抱歉,遗漏了一些数学逻辑……当您需要全部增加时(假设您要增加 maxHeight)怎么办? 这可以单独使用 CSS 完成吗? (最大宽度、高度:自动等?) 不确定为什么需要 jQuery。在客户端按比例缩小图像可以使用 CSS 完成,而且很简单:只需将其 max-widthmax-height 设置为 100%。 jsfiddle.net/9EQ5c 由于 IF 语句,这不能用 CSS 完成。我相信重点是填写缩略图。如果图像太高,它必须是最大宽度,如果图像太宽,它必须是最大高度。如果你做 CSS max-width, max-height,你会得到带有空格而不是完全填充的缩略图 这段代码是否会导致浏览器出现问题、崩溃或变慢??【参考方案2】:

如果图像是成比例的,那么此代码将用图像填充包装器。如果图像不成比例,则额外的宽度/高度将被裁剪。

    <script type="text/javascript">
        $(function()
            $('#slider img').each(function()
                var ReqWidth = 1000; // Max width for the image
                var ReqHeight = 300; // Max height for the image
                var width = $(this).width(); // Current image width
                var height = $(this).height(); // Current image height
                // Check if the current width is larger than the max
                if (width > height && height < ReqHeight) 

                    $(this).css("min-height", ReqHeight); // Set new height
                
                else 
                    if (width > height && width < ReqWidth) 

                        $(this).css("min-width", ReqWidth); // Set new width
                    
                    else 
                        if (width > height && width > ReqWidth) 

                            $(this).css("max-width", ReqWidth); // Set new width
                        
                        else 
                            (height > width && width < ReqWidth)
                

                    $(this).css("min-width", ReqWidth); // Set new width
                
            );
        );
    </script>

【讨论】:

【参考方案3】:
$('#productThumb img').each(function() 
    var maxWidth = 140; // Max width for the image
    var maxHeight = 140;    // Max height for the image
    var ratio = 0;  // Used for aspect ratio
    var width = $(this).width();    // Current image width
    var height = $(this).height();  // Current image height
    // Check if the current width is larger than the max
    if(width > height)
        height = ( height / width ) * maxHeight;

     else if(height > width)
        maxWidth = (width/height)* maxWidth;
    
    $(this).css("width", maxWidth); // Set new width
    $(this).css("height", maxHeight);  // Scale height based on ratio
);

【讨论】:

请考虑在回答帖子时添加解释,而不仅仅是代码。【参考方案4】:

这个问题有4个参数

    当前图像宽度 iX 当前图像高度 iY 目标视口宽度 cX 目标视口高度 cY

并且有3个不同的条件参数

    cX > cY ? iX > cX ? iY > cY ?

解决方案

    找到目标视口 F 的较小边 找到当前视口 L 较大的一侧 找出 F/L = 因子的因子 将当前端口的两边乘以因子,即fX = iX * 因子; fY = iY * 因子

这就是你需要做的。

//Pseudo code


iX;//current width of image in the client
iY;//current height of image in the client
cX;//configured width
cY;//configured height
fX;//final width
fY;//final height

1. check if iX,iY,cX,cY values are >0 and all values are not empty or not junk

2. lE = iX > iY ? iX: iY; //long edge

3. if ( cX < cY )
   then
4.      factor = cX/lE;     
   else
5.      factor = cY/lE;

6. fX = iX * factor ; fY = iY * factor ; 

这是一个成熟的论坛,我不会给你代码:)

【讨论】:

发布这背后的方法很棒,但我标记你并没有通过发布代码来真正帮助用户。好像有点碍事 "谁能给我一些代码,或者解释一下逻辑?" - 很明显,他可以只向他解释方法。就个人而言,我认为这将是帮助某人更好的方式,帮助他们理解方法而不是让他们复制和粘贴代码。 @JessMcintosh,可惜对原始问题的大量编辑使您的评论脱离了上下文:)【参考方案5】:

其实我刚刚遇到这个问题,我发现的解决方案出奇的简单和奇怪

$("#someimage").css(height:<some new height>)

奇迹般地,图像被调整到新的高度并保持相同的比例!

【讨论】:

我认为这很有用 - 但我想如果非常非常宽,它不会限制图像到最大宽度...... 这个东西在你不设置其他属性时有效。 (在这种情况下是宽度)【参考方案6】:

如果我正确理解了这个问题,那么您甚至不需要 jQuery。仅使用 CSS 即可在客户端按比例缩小图像:只需将其 max-widthmax-height 设置为 100%

<div style="height: 100px">
  <img src="http://www.getdigital.de/images/produkte/t4/t4_css_sucks2.jpg" 
  style="max-height: 100%; max-width: 100%">
</div>​

这是小提琴:http://jsfiddle.net/9EQ5c/

【讨论】:

这是一个比上面更容易的答案。谢谢。顺便说一句,您是如何获得“我的答案”链接以向下滚动到您的帖子的? @SnareChops:它只是一个html anchor。 @SnareChops:如果您使用答案下方“分享”链接给出的链接,它也会滚动到答案。 @Flimm 因为跨度不显示:默认阻止。只需添加 display: 块,或将其设为 div。 在我的例子中,IMG 是用 WordPress 渲染的,所以它设置了宽度和高度。在 CSS 中,我还必须设置 width: auto; height: auto; 才能让您的代码运行 :)【参考方案7】:

我觉得这真的是cool method:

 /**
  * Conserve aspect ratio of the original region. Useful when shrinking/enlarging
  * images to fit into a certain area.
  *
  * @param Number srcWidth width of source image
  * @param Number srcHeight height of source image
  * @param Number maxWidth maximum available width
  * @param Number maxHeight maximum available height
  * @return Object  width, height 
  */
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) 

    var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);

    return  width: srcWidth*ratio, height: srcHeight*ratio ;
 

【讨论】:

非常优秀的答案!如果高度和宽度都较大,则正确答案会平展。真的,很好,小胡子也很漂亮。 +1 非常简洁。声明function calculateAspectRatioFit(dimensions) /* then use such as dimensions.maxWidth , dimensions.srcWidth ...*/ 之类的函数,然后调用function( maxWidth: someWidth, srcWidth: someOtherWith, maxHeight: someHeight, srcHeight: someOtherHeight );之类的呢?这对于避免参数顺序问题很有用。 那将是理想的@AdrienBe,但这个问题在一年多前就得到了回答,我认为它很简单,可以适应个人定制。 :) 你说得对@sstauross,十进制像素可以有一点unexpected results。然而,在我的用例中,它可以忽略不计。我想Math.floor 将真正有助于 pixel perfect 设计:-) 这是处理这个问题的绝妙方法!我对 img 元素进行了一些调整 + 防止放大图像:function imgSizeFit(img, maxWidth, maxHeight) var ratio = Math.min(1, maxWidth / img.naturalWidth, maxHeight / img.naturalHeight); img.style.width = img.naturalWidth * ratio + 'px'; img.style.height = img.naturalHeight * ratio + 'px'; 【参考方案8】:

这对我来说完全适用于可拖动项目 - aspectRatio:true

.appendTo(divwrapper).resizable(
    aspectRatio: true,
    handles: 'se',
    stop: resizestop 
)

【讨论】:

【参考方案9】:

没有额外的临时变量或括号。

    var width= $(this).width(), height= $(this).height()
      , maxWidth=100, maxHeight= 100;

    if(width > maxWidth)
      height = Math.floor( maxWidth * height / width );
      width = maxWidth
      
    if(height > maxHeight)
      width = Math.floor( maxHeight * width / height );
      height = maxHeight;
      

记住:搜索引擎不喜欢它,如果宽度和高度属性不适合图像,但他们不知道 JS。

【讨论】:

【参考方案10】:

&lt;img src="/path/to/pic.jpg" style="max-width:XXXpx; max-height:YYYpx;" &gt; 有帮助吗?

浏览器将负责保持纵横比不变。

max-width 在图像宽度大于高度时启动,其高度将按比例计算。同样max-height 将在高度大于宽度时生效。

您不需要任何 jQuery 或 javascript。

ie7+等浏览器支持(http://caniuse.com/minmaxwh)。

【讨论】:

很棒的提示!只是将 CSS 放在 CSS 文件中,而不是直接放在 html 代码中。 我认为这样做的问题是,当您在页面加载之前不知道最大宽度和最大高度是多少时,它将不起作用。这就是需要 JS 解决方案的原因。这通常是响应式网站的情况。【参考方案11】:

经过反复试验,我得出了这个解决方案:

function center(img) 
    var div = img.parentNode;
    var divW = parseInt(div.style.width);
    var divH = parseInt(div.style.height);
    var srcW = img.width;
    var srcH = img.height;
    var ratio = Math.min(divW/srcW, divH/srcH);
    var newW = img.width * ratio;
    var newH = img.height * ratio;
    img.style.width  = newW + "px";
    img.style.height = newH + "px";
    img.style.marginTop = (divH-newH)/2 + "px";
    img.style.marginLeft = (divW-newW)/2 + "px";

【讨论】:

【参考方案12】:

为了确定aspect ratio,您需要有一个目标比率。

function getHeight(length, ratio) 
  var height = ((length)/(Math.sqrt((Math.pow(ratio, 2)+1))));
  return Math.round(height);

function getWidth(length, ratio) 
  var width = ((length)/(Math.sqrt((1)/(Math.pow(ratio, 2)+1))));
  return Math.round(width);

在本例中,我使用16:10,因为这是典型的显示器纵横比。

var ratio = (16/10);
var height = getHeight(300,ratio);
var width = getWidth(height,ratio);

console.log(height);
console.log(width);

上面的结果将是 147300

【讨论】:

考虑到,300=对角线宽度=高度*比例和高度和你说的一样【参考方案13】:

这应该适用于所有可能比例的图像

$(document).ready(function() 
    $('.list img').each(function() 
        var maxWidth = 100;
        var maxHeight = 100;
        var width = $(this).width();
        var height = $(this).height();
        var ratioW = maxWidth / width;  // Width ratio
        var ratioH = maxHeight / height;  // Height ratio

        // If height ratio is bigger then we need to scale height
        if(ratioH > ratioW)
            $(this).css("width", maxWidth);
            $(this).css("height", height * ratioW);  // Scale height according to width ratio
        
        else // otherwise we scale width
            $(this).css("height", maxHeight);
            $(this).css("width", height * ratioH);  // according to height ratio
        
    );
);

【讨论】:

【参考方案14】:

可以使用 CSS 实现调整大小(保持纵横比)。 这是受 Dan Dascalescu 的帖子启发而进一步简化的答案。

http://jsbin.com/viqare

img
     max-width:200px;
 /*Or define max-height*/
  
<img src="http://e1.365dm.com/13/07/4-3/20/alastair-cook-ashes-profile_2967773.jpg"   />

<img src="http://e1.365dm.com/13/07/4-3/20/usman-khawaja-australia-profile_2974601.jpg" />

【讨论】:

【参考方案15】:

这是对 Mehdiway 答案的更正。新的宽度和/或高度未设置为最大值。以下是一个很好的测试用例(1768 x 1075 像素):http://spacecoastsports.com/wp-content/uploads/2014/06/sportsballs1.png。 (由于缺乏声望点,我无法在上面对此发表评论。)

  // Make sure image doesn't exceed 100x100 pixels
  // note: takes jQuery img object not HTML: so width is a function
  // not a property.
  function resize_image (image) 
      var maxWidth = 100;           // Max width for the image
      var maxHeight = 100;          // Max height for the image
      var ratio = 0;                // Used for aspect ratio

      // Get current dimensions
      var width = image.width()
      var height = image.height(); 
      console.log("dimensions: " + width + "x" + height);

      // If the current width is larger than the max, scale height
      // to ratio of max width to current and then set width to max.
      if (width > maxWidth) 
          console.log("Shrinking width (and scaling height)")
          ratio = maxWidth / width;
          height = height * ratio;
          width = maxWidth;
          image.css("width", width);
          image.css("height", height);
          console.log("new dimensions: " + width + "x" + height);
      

      // If the current height is larger than the max, scale width
      // to ratio of max height to current and then set height to max.
      if (height > maxHeight) 
          console.log("Shrinking height (and scaling width)")
          ratio = maxHeight / height;
          width = width * ratio;
          height = maxHeight;
          image.css("width", width);
          image.css("height", height);
          console.log("new dimensions: " + width + "x" + height);
      
  

【讨论】:

【参考方案16】:

2 步:

步骤1)计算Image的原始宽度/原始高度的比率。

步骤 2)将 original_width/original_height 比率乘以新的所需高度,得到新高度对应的新宽度。

【讨论】:

【参考方案17】:

这个问题可以通过 CSS 解决。

.image
 max-width:*px;

【讨论】:

【参考方案18】:

调整大小以适应容器,获取比例因子,缩小百分比控制

 $(function () 
            let ParentHeight = 200;
            let ParentWidth = 300;
            $("#Parent").width(ParentWidth).height(ParentHeight);
            $("#ParentHeight").html(ParentHeight);
            $("#ParentWidth").html(ParentWidth);

            var RatioOfParent = ParentHeight / ParentWidth;
            $("#ParentAspectRatio").html(RatioOfParent);

            let ChildHeight = 2000;
            let ChildWidth = 4000;
            var RatioOfChild = ChildHeight / ChildWidth;
            $("#ChildAspectRatio").html(RatioOfChild);

            let ScaleHeight = ParentHeight / ChildHeight;
            let ScaleWidth = ParentWidth / ChildWidth;
            let Scale = Math.min(ScaleHeight, ScaleWidth);

            $("#ScaleFactor").html(Scale);
            // old scale
            //ChildHeight = ChildHeight * Scale;
            //ChildWidth = ChildWidth * Scale;

            // reduce scale by 10%, you can change the percentage
            let ScaleDownPercentage = 10;
            let CalculatedScaleValue = Scale * (ScaleDownPercentage / 100);
            $("#CalculatedScaleValue").html(CalculatedScaleValue);

            // new scale
            let NewScale = (Scale - CalculatedScaleValue);
            ChildHeight = ChildHeight * NewScale;
            ChildWidth = ChildWidth * NewScale;

            $("#Child").width(ChildWidth).height(ChildHeight);
            $("#ChildHeight").html(ChildHeight);
            $("#ChildWidth").html(ChildWidth);

        );
        #Parent 
            background-color: grey;
        

        #Child 
            background-color: red;
        
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Parent">
    <div id="Child"></div>
</div>

<table>
    <tr>
        <td>Parent Aspect Ratio</td>
        <td id="ParentAspectRatio"></td>
    </tr>
    <tr>
        <td>Child Aspect Ratio</td>
        <td id="ChildAspectRatio"></td>
    </tr>
    <tr>
        <td>Scale Factor</td>
        <td id="ScaleFactor"></td>
    </tr>
    <tr>
        <td>Calculated Scale Value</td>
        <td id="CalculatedScaleValue"></td>
    </tr>
    <tr>
        <td>Parent Height</td>
        <td id="ParentHeight"></td>
    </tr>
    <tr>
        <td>Parent Width</td>
        <td id="ParentWidth"></td>
    </tr>
    <tr>
        <td>Child Height</td>
        <td id="ChildHeight"></td>
    </tr>
    <tr>
        <td>Child Width</td>
        <td id="ChildWidth"></td>
    </tr>
</table>

【讨论】:

【参考方案19】:

将图像大小调整到特定百分比

// scale can be 0.40, 0.80, etc.
function imageScaler(originalHeight, originalWidth, scale) 
  const scaledWidth = originalWidth * scale;
  const scaledHeight = (originalHeight / originalWidth) * scaledWidth;
  return [scaledHeight, scaledWidth];

【讨论】:

【参考方案20】:

如果您想要特定的纵横比,您可以确定宽度高度, 让你拥有一张3264×2448的图片 图片纵横比 => 2448 ÷ 3264 =0.75 现在只需检查在除法上给出 0.75 的数字。 像 16:9 => 9÷16 =0.5625(错不是0.75) 现在 4:3 =>3÷4=0.75(我们明白了) 所以原来的纵横比是4:3 现在调整图像大小 宽度=3264÷/×4 高度=2448 ÷/× 3 ÷ 用于减少 × 增加 希望你能理解并自己编写代码,这是非常有效的,因为我们只需要进行非常基本的算术运算,除法或乘法如此简单。 如果我错了,请告诉我。

【讨论】:

我无法格式化此文档,因此请有人对其进行编辑并使其可读。我不知道该怎么做,对不起

以上是关于如何按比例调整图像大小/保持纵横比?的主要内容,如果未能解决你的问题,请参考以下文章

如何在保持图像纵横比的同时调整 UIButton 中的图像大小?

在不保持纵横比的情况下使用 mogrify 调整图像大小

iMessage App如何调整图像大小并保持纵横比

如何使用保持纵横比的 QHBLayout 调整子 QLabel(具有 QPixmap)的大小?

调整图像大小保持纵横比

在 CSS FlexBox 布局中自动调整图像大小并保持纵横比?