缩放图像以适合边界框

Posted

技术标签:

【中文标题】缩放图像以适合边界框【英文标题】:Scale image to fit a bounding box 【发布时间】:2012-04-17 04:18:42 【问题描述】:

是否有仅使用 css 的解决方案将图像缩放到边界框(保持纵横比)?如果图像大于容器,则此方法有效:

img 
  max-width: 100%;
  max-height: 100%;

例子:

用例 1(有效):http://jsfiddle.net/Jp5AQ/2/ 用例 2(有效):http://jsfiddle.net/Jp5AQ/3/

但我想放大图像直到尺寸为容器的 100%。

用例 3(不起作用):http://jsfiddle.net/Jp5AQ/4/

【问题讨论】:

你的意思是像 height: 100% 和 width: 100% 吗?你有想要达到的维度吗?否则你也可以拉伸图像并强制它达到这些尺寸。 @mikevoermans 看看我的前两个例子:我想拉伸图像直到一个尺寸为 100%,另一个为 @jacktheripper 当然要保持纵横比... @gryzzly 例子不言自明!如果他们看过这些例子,那是显而易见的。 @Artimuz 我完全不同意。您的问题的三个答案(包括我的)表明这并不明显。 【参考方案1】:

这符合我的需要,在设置高度限制时不会使图像变平,而是溢出。

.top-container
       width:50%;
    
.img-container 
        display: flex;
        justify-content: center;
        align-items: center;
        height: 40vh;
        width: 100%;
        overflow: hidden;
    
    
    .img-container img 
        max-width: 10%;
        max-height: auto;
        transform: scale(10);
    
<div class='top-container'>
 <div class='img-container'>
  <img src='image.jpg'>
 </div>
</div>

【讨论】:

【参考方案2】:

在 div 和 img 上使用 Object Fit 来缩放图像

<div class="box"><img src="image.jpg"></div>

.box height: auto;
object-fit: cover; 

img  height: 100%; object-fit: cover; 

【讨论】:

你能edit你的答案解释为什么你的帖子不同/更好吗?【参考方案3】:

注意:尽管这是公认的答案,但the answer below 更准确,如果您可以选择使用背景图片,目前所有浏览器都支持。

编辑 2:在现代,使用 object-fit 可能是更好的解决方案:https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

不,没有 CSS 唯一的方法可以双向执行此操作。你可以添加

.fillwidth 
    min-width: 100%;
    height: auto;

对于一个元素,使其始终具有 100% 的宽度并自动将高度缩放为纵横比,相反:

.fillheight 
    min-height: 100%; 
    width: auto;

始终缩放到最大高度和相对宽度。要同时做到这两点,您需要确定纵横比是高于还是低于其容器,而 CSS 无法做到这一点。

原因是 CSS 不知道页面的样子。它预先设置规则,但只有在此之后,元素才会被渲染,并且您确切知道您正在处理的大小和比率。检测它的唯一方法是使用 javascript


虽然您不是在寻找 JS 解决方案,但如果有人可能需要,我还是会添加一个。使用 JavaScript 处理此问题的最简单方法是根据比率差异添加一个类。如果框的宽高比大于图像的宽高比,则添加“fillwidth”类,否则添加“fillheight”类。

$('div').each(function() 
  var fillClass = ($(this).height() > $(this).width()) 
    ? 'fillheight'
    : 'fillwidth';
  $(this).find('img').addClass(fillClass);
);
.fillwidth  
  width: 100%; 
  height: auto; 

.fillheight  
  height: 100%; 
  width: auto; 


div 
  border: 1px solid black;
  overflow: hidden;


.tower 
  width: 100px;
  height: 200px;


.trailer 
  width: 200px;
  height: 100px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tower">
  <img src="http://placekitten.com/150/150" />
</div>
<div class="trailer">
  <img src="http://placekitten.com/150/150" />
</div>

【讨论】:

其实有一个解决办法:设置CSS3 background-size 为contain。看我的回答。 你完全正确。尽管现在已经过了一年半,我还是编辑了我的帖子。 我认为这是问题的正确答案,即 img 标签的 CSS 是什么。这是相关的,因为在语义上 img 标签是内容,而作为 div 背景的图像不是。虽然在某些情况下这不切实际(如果您不知道图像与容器的比例),但对于其他情况来说,这是正确的。谢谢。 致所有像我一样在 Google 上找到此内容的人:您可以使用 object-fit 和纯 CSS 来做到这一点。 developer.mozilla.org/en-US/docs/Web/CSS/object-fit 感谢@lxhom,也添加了该信息:)【参考方案4】:

我使用表格将图像居中放置在框内。它以完全在盒子内的方式保持纵横比和缩放图像。如果图像小于框,则显示为中心。下面的代码使用 40px 宽度和 40px 高度框。 (不太确定它的效果如何,因为我将它从另一个更复杂的代码中删除并稍微简化了一点)

.SmallThumbnailContainer 
  display: inline-block;
  position: relative;
  float: left;
  width: 40px;
  height: 40px;
  border: 1px solid #ccc;
  margin: 0px;
  padding: 0px;


.SmallThumbnailContainer 
  width: 40px;
  margin: 0px 10px 0px 0px;


.SmallThumbnailContainer tr 
  height: 40px;
  text-align: center;


.SmallThumbnailContainer tr td 
  vertical-align: middle;
  position: relative;
  width: 40px;


.SmallThumbnailContainer tr td img 
  overflow: hidden;
  max-height: 40px;
  max-width: 40px;
  vertical-align: middle;
  margin: -1px -1px 1px -1px;
<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
  <tr>
    <td>
      <img src="https://www.gravatar.com/avatar/bf7d39f4ed9c289feca7de38a0093250?s=32&d=identicon&r=PG"    />
    </td>
  </tr>
</table>

注意:此 sn-p 中的原生缩略图大小为 32px x 32px,小于其 40px x 40px 容器。如果容器的尺寸小于任何尺寸的缩略图,例如 40 像素 x 20 像素,则图像以小于相应图像尺寸的尺寸流出容器。容器由 1px 的灰色边框标记。

【讨论】:

【参考方案5】:

这是我发现的一个骇人听闻的解决方案:

#image 
    max-width: 10%;
    max-height: 10%;
    transform: scale(10);

这会将图像放大十倍,但将其限制为最终大小的 10% - 从而将其绑定到容器中。

background-image 解决方案不同,这也适用于&lt;video&gt; 元素。

交互示例:

 function step(timestamp) 
     var container = document.getElementById('container');
     timestamp /= 1000;
     container.style.left   = (200 + 100 * Math.sin(timestamp * 1.0)) + 'px';
     container.style.top    = (200 + 100 * Math.sin(timestamp * 1.1)) + 'px';
     container.style.width  = (500 + 500 * Math.sin(timestamp * 1.2)) + 'px';
     container.style.height = (500 + 500 * Math.sin(timestamp * 1.3)) + 'px';
     window.requestAnimationFrame(step);
 

 window.requestAnimationFrame(step);
 #container 
     outline: 1px solid black;
     position: relative;
     background-color: red;
 
 #image 
     display: block;
     max-width: 10%;
     max-height: 10%;
     transform-origin: 0 0;
     transform: scale(10);
 
<div id="container">
    <img id="image" src="https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png">
</div>

【讨论】:

我喜欢这个解决方案。它不仅真正回答了这个问题(我知道,这是一个多么好的想法),它在所有现代浏览器中都能很好地工作,而无需求助于 Javascript! 我很想看看这个。在我将 img 放置在 400x400 容器中的测试中,img 只是在角落里被裁剪 不错的答案! @Yashua 您需要添加 transform-origin: top left 以停止裁剪。 /僵尸 有趣,但不适用于 Chrome。生成图像的裁剪行。 @Konstantin Scaling 只有在您还想放大图像时才需要(当它小于容器的宽度或高度时)。【参考方案6】:

您可以使用纯 CSS 和完整的浏览器支持来实现这一点,同时适用于垂直长和水平长的图像。

这是一个适用于 Chrome、Firefox 和 Safari 的 sn-p(都使用 object-fit: scale-down,并且不使用它):

figure 
  margin: 0;


.container 
  display: table-cell;
  vertical-align: middle;
  width: 80px;
  height: 80px;
  border: 1px solid #aaa;


.container_image 
  display: block;
  max-width: 100%;
  max-height: 100%;
  margin-left: auto;
  margin-right: auto;


.container2_image2 
  width: 80px;
  height: 80px;
  object-fit: scale-down;
  border: 1px solid #aaa;
Without `object-fit: scale-down`:

<br>
<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

<br> Using `object-fit: scale-down`:

<br>
<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

【讨论】:

【参考方案7】:

html:

    <div class="container">
      <img class="flowerImg" src="flower.jpg">
    </div>

css:

.container
  width: 100px;
  height: 100px;



.flowerImg
  width: 100px;
  height: 100px;
  object-fit: cover;
  /*object-fit: contain;
  object-fit: scale-down;
  object-position: -10% 0;
  object-fit: none;
  object-fit: fill;*/

【讨论】:

【参考方案8】:

另一种没有背景图像且不需要容器的解决方案(尽管必须知道边界框的最大尺寸):

img
  max-height: 100px;
  max-width: 100px;
  width: auto;    /* These two are added only for clarity, */
  height: auto;   /* as the default is auto anyway */


如果需要使用容器,则可以将 max-width 和 max-height 设置为 100%:
img 
    max-height: 100%;
    max-width: 100%;
    width: auto; /* These two are added only for clarity, */
    height: auto; /* as the default is auto anyway */


div.container 
    width: 100px;
    height: 100px;

为此,您将有类似的内容:

<table>
    <tr>
        <td>Lorem</td>
        <td>Ipsum<br />dolor</td>
        <td>
            <div class="container"><img src="image5.png" /></div>
        </td>
    </tr>
</table>

【讨论】:

【参考方案9】:

这对我有帮助:

.img-class 
  width: <img width>;
  height: <img height>;
  content: url('/path/to/img.png');

然后在元素上(可以使用 javascript 或媒体查询来添加响应性):

<div class='img-class' style='transform: scale(X);'></div>

希望这会有所帮助!

【讨论】:

【参考方案10】:

今天,只说object-fit:contain。除了 IE,支持就是一切:http://caniuse.com/#feat=object-fit

【讨论】:

在撰写本文时(2016 年 9 月 12 日上午 10 点 56 分),IE 现在只有大约 16% 的市场份额并且还在继续减少,所以这对我来说是最好的答案:D 不要编辑其他人的答案来修复拼写错误或损坏的链接以外的问题。我不会在 SO 答案中说“有一个用于垃圾浏览器的 polyfill”之类的幼稚的话,而且我不欣赏我的答案被编辑以使其看起来像我说的那样。如果你想用你的话,把它们放在你自己的答案中。 我想说,问题不是 IE,而是 Edge。根据 caniuse 的说法,object-fit 仍在开发中。 这应该是 2017 年及以后投票最多的答案之一...根据上面的 caniuse 链接,全球 90% 的用户现在使用支持此功能的浏览器 我刚刚发布了一个可以使用和不使用object-fit的答案:***.com/a/46456673/474031【参考方案11】:

最干净和最简单的方法:

首先是一些 CSS:

div.image-wrapper 
    height: 230px; /* Suggestive number; pick your own height as desired */
    position: relative;
    overflow: hidden; /* This will do the magic */
    width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */

img 
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    height: auto;

HTML:

<div class="image-wrapper">
  <img src="yourSource.jpg">
</div>

这应该可以解决问题!

【讨论】:

【参考方案12】:
.boundingbox 
    width: 400px;
    height: 500px;
    border: 2px solid #F63;

img
    width:400px;
    max-height: 500px;
    height:auto;

我正在编辑我的答案以进一步解释我的解决方案,因为我投了反对票。

在css中设置了如上所示的样式,现在以下html div将显示图像始终适合宽度,并将调整高宽比到宽度。因此,图像将按照问题中的要求缩放以适合边界框

<div class="boundingbox"><img src="image.jpg"/></div>

【讨论】:

此答案仅适用于盒子的高度大于宽度的情况。【参考方案13】:

此示例按比例拉伸图像以适合整个窗口。 对上述正确代码的即兴创作是添加$( window ).resize(function());

function stretchImg()
    $('div').each(function() 
      ($(this).height() > $(this).find('img').height()) 
        ? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
        : '';
      ($(this).width() > $(this).find('img').width()) 
        ? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
        : '';
    );

stretchImg();

$( window ).resize(function() 
    strechImg();
);

有两个 if 条件。第一个继续检查图像高度是否小于 div 并应用 .fillheight 类,而下一个检查宽度并应用 .fillwidth 类。 在这两种情况下,使用 .removeClass() 删除另一个类

这里是 CSS

.fillwidth  
   width: 100%;
   max-width: none;
   height: auto; 

.fillheight  
   height: 100vh;
   max-width: none;
   width: auto; 

如果要在 div 中拉伸图像,可以将 100vh 替换为 100%。此示例按比例拉伸图像以适合整个窗口。

【讨论】:

OP 专门要求使用纯 CSS 方法。【参考方案14】:

感谢 CSS3 有一个解决方案!

解决方法是将图片设置为background-image,然后将background-size设置为contain

HTML

<div class='bounding-box'>
</div>

CSS

.bounding-box 
  background-image: url(...);
  background-repeat: no-repeat;
  background-size: contain;

在这里测试:http://www.w3schools.com/cs-s-ref/playit.asp?filename=playcss_background-size&preval=contain

完全兼容最新浏览器:http://caniuse.com/background-img-opts

要将 div 居中对齐,您可以使用以下变体:

.bounding-box 
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;

【讨论】:

不错,虽然我的回答并不正确(您是在专门询问 img),但这是一个很好的解决方案,我应该想到这一点。唯一的问题是 IE 8 仍然被广泛使用,我还不想依赖它,但还是不错的。 如果您不想要任何信箱,请将其设置为“覆盖”:背景大小:包含; 需要注意的是,您可以使用 HTML 注入图像 URL:&lt;div class=image style="background-image: url('/images/foo.jpg');"&gt;&lt;/div&gt;。所有其他样式都应使用 CSS。 我会说这是一种糟糕的方法。通过将其更改为背景图像,您将删除 HTML 中图像的语义含义。 @animuson:它仍然对我有帮助,因为我正在使用 HTML/CSS 打印报告,并且无法对语义发表意见 :)【参考方案15】:

您是否希望向上扩展而不是向下扩展?

div 
    border: solid 1px green;
    width: 60px;
    height: 70px;


div img 
    width: 100%;
    height: 100%;
    min-height: 500px;
    min-width: 500px;
    outline: solid 1px red;

但是,这不会锁定纵横比。

【讨论】:

在否决某人的答案之前,请尝试更清楚您的期望。尤其是当他们在您通过编辑解决问题之前回答了您的问题时。 另外,尽量礼貌一点。如果你这样说话,没有人会帮助你。 @Artimuz 如果我误导了您,我深表歉意,但我似乎不清楚您是否希望保持纵横比,这就是我特别评论的原因。此外,您会注意到我从示例中粘贴了您的代码的 sn-p。我相信保持高度:自动;如果您指定宽度,将为您执行此操作。

以上是关于缩放图像以适合边界框的主要内容,如果未能解决你的问题,请参考以下文章

AS3 图像在内部旋转/缩放以适合精灵

在方向更改时自动缩放 UIView 以按比例缩放以适合父视图

Android Webview - 使用一个 loadUrl 缩放图像以正确适合屏幕

如何使用 QPainter 缩放文本以适合边界框?

缩放对象以适合某些边界框three.js

C ++ Opencv重新缩放边界矩形