缩放图像以适合边界框
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
解决方案不同,这也适用于<video>
元素。
交互示例:
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:<div class=image style="background-image: url('/images/foo.jpg');"></div>
。所有其他样式都应使用 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。我相信保持高度:自动;如果您指定宽度,将为您执行此操作。以上是关于缩放图像以适合边界框的主要内容,如果未能解决你的问题,请参考以下文章
在方向更改时自动缩放 UIView 以按比例缩放以适合父视图