如何自动裁剪和居中图像
Posted
技术标签:
【中文标题】如何自动裁剪和居中图像【英文标题】:How to automatically crop and center an image 【发布时间】:2012-07-18 03:19:06 【问题描述】:给定任意图像,我想从图像的中心裁剪一个正方形并将其显示在给定的正方形内。
这个问题类似于:CSS Display an Image Resized and Cropped,但我不知道图像的大小,所以我不能使用设置边距。
【问题讨论】:
元素必须是图片标签,还是可以是带有背景图片属性的div? 只要我可以通过我的模板系统设置图像,没关系。有点难看,但我想内联样式会起作用。 【参考方案1】:我一直在寻找使用img
标签(不是背景图像方式)的纯 CSS 解决方案。
我在crop thumbnails with css 上找到了实现目标的绝妙方法:
.thumbnail
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
.thumbnail img
position: absolute;
left: 50%;
top: 50%;
height: 100%;
width: auto;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
.thumbnail img.portrait
width: 100%;
height: auto;
这类似于@Nathan Redblur 的回答,但它也允许纵向图像。
对我来说就像一个魅力。关于图像,您唯一需要知道的是它是纵向还是横向,以便设置 .portrait
类,所以我不得不在这部分使用一些 javascript。
【讨论】:
请注意 CSS 转换仅在 IE 9 及更高版本中可用。 这应该是答案。 OP 说“任意图像”,所以如果图像的高度大于宽度,则不会预先知道。 如果你把 min-height:100%;min-width:100%;而不是高度:100%;宽度:自动;你不需要 img.portrait 类。 结合@user570605 建议的最佳解决方案【参考方案2】:一种解决方案是使用以裁剪尺寸为大小的元素中居中的背景图像。
基本示例
.center-cropped
width: 100px;
height: 100px;
background-position: center center;
background-repeat: no-repeat;
<div class="center-cropped"
style="background-image: url('http://placehold.it/200x200');">
</div>
img
标签示例
这个版本保留了img
标签,这样我们就不会失去拖动或右键保存图像的能力。感谢 Parker Bennett 的不透明技巧。
.center-cropped
width: 100px;
height: 100px;
background-position: center center;
background-repeat: no-repeat;
overflow: hidden;
/* Set the image to fill its parent and make transparent */
.center-cropped img
min-height: 100%;
min-width: 100%;
/* IE 8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
/* IE 5-7 */
filter: alpha(opacity=0);
/* modern browsers */
opacity: 0;
<div class="center-cropped"
style="background-image: url('http://placehold.it/200x200');">
<img src="http://placehold.it/200x200" />
</div>
object-fit
/-position
See supported browsers.
CSS3 Images specification 定义了object-fit
和object-position
属性,它们共同允许更好地控制img
元素的图像内容的比例和位置。有了这些,就可以达到预期的效果:
.center-cropped
object-fit: none; /* Do not scale the image */
object-position: center; /* Center the image within the element */
height: 100px;
width: 100px;
<img class="center-cropped" src="http://placehold.it/200x200" />
【讨论】:
您可以使用background-size: cover;
使图像在保持原始纵横比的同时适当缩小或填充div。
使用 background-image 时,您应该添加 background-size:cover 以正确调整裁剪图像的大小:参见jsfiddle.net/bw6ct
有人告诉我,现在谷歌知道透明和隐藏图像,所以 img
的 alt
ant title
属性将丢失您的 SEO。
在webkit中你也可以直接在img标签上使用object-fit: cover;
,感觉更语义化。
我使用 object-fit:cover 来获得我想要的不丢失纵横比的效果,覆盖正方形,并在需要时进行裁剪【参考方案3】:
试试这个:设置您的图像裁剪尺寸并在您的 CSS 中使用此行:
object-fit: cover;
【讨论】:
不太支持:caniuse.com/#feat=object-fit 编辑:实际上,像往常一样,只是 MS 浏览器在这方面失败了......虽然它确实代表了相当多的使用:/ 这正是我需要的:) 唯一不支持此功能的广泛使用的浏览器是 Internet Explorer 11 和 Edge。根据您的受众,目前的支持率可能在 85-90% 左右,这在某些情况下可能是可行的。 国王!很棒的解决方案! 还有一个很好的教程:medium.com/@chrisnager/…【参考方案4】:还有另一种方法可以使图像居中裁剪:
.thumbnailposition: relative; overflow: hidden; width: 320px; height: 640px;
.thumbnail img
position: absolute; top: -999px; bottom: -999px; left: -999px; right: -999px;
width: auto !important; height: 100% !important; margin: auto;
.thumbnail img.verticalwidth: 100% !important; height: auto !important;
您唯一需要的是将“垂直”类添加到垂直图像,您可以使用以下代码来完成:
jQuery(function($)
$('img').one('load', function ()
var $img = $(this);
var tempImage1 = new Image();
tempImage1.src = $img.attr('src');
tempImage1.onload = function()
var ratio = tempImage1.width / tempImage1.height;
if(!isNaN(ratio) && ratio < 1) $img.addClass('vertical');
).each(function ()
if (this.complete) $(this).load();
);
);
注意:“!important”用于覆盖img标签上可能的宽度、高度属性。
【讨论】:
【参考方案5】:带有img
标签但没有background-image
的示例
这个解决方案保留了img
标签,这样我们就不会失去拖动或右键单击保存图像的能力,但没有background-image
,只需居中并使用css裁剪。
保持宽高比正常,除非在非常高的图像中。 (查看链接)
(view in action)
标记
<div class="center-cropped">
<img src="http://placehold.it/200x150" />
</div>
CSS
div.center-cropped
width: 100px;
height: 100px;
overflow:hidden;
div.center-cropped img
height: 100%;
min-width: 100%;
left: 50%;
position: relative;
transform: translateX(-50%);
【讨论】:
试试这个...如果图像小于容器,它将居中,否则将裁剪jsfiddle.net/3ts4rm24/1 为什么将left: 50%
与transform: translateX(-50%)
一起使用?
left
是与容器相关的位置translate
与元素相关如果你的容器是100px,而你的图片是20px,left
会将图片放在50px之间的位置- 70像素。为了解决这个问题,我们将图片的大小设置为translateX(-50%)
,然后您的图片将在 40px-60px 之间。 Ej:如果你的容器是100px,left: 50%
这个容器的rightMiddle = container/2 - element/2【参考方案6】:
我使用@Russ 和@Alex 的答案创建了一个 angularjs 指令
在 2014 年及以后可能会很有趣:P
<div ng-app="croppy">
<cropped-image src="http://placehold.it/200x200" ></cropped-image>
</div>
js
angular.module('croppy', [])
.directive('croppedImage', function ()
return
restrict: "E",
replace: true,
template: "<div class='center-cropped'></div>",
link: function(scope, element, attrs)
var width = attrs.width;
var height = attrs.height;
element.css('width', width + "px");
element.css('height', height + "px");
element.css('backgroundPosition', 'center center');
element.css('backgroundRepeat', 'no-repeat');
element.css('backgroundImage', "url('" + attrs.src + "')");
);
fiddle link
【讨论】:
嗨,反对者。请发表评论,以便如果有错误我可以更新我的答案。我不喜欢提供虚假信息。干杯。 不是反对者,但这不是 Angular 问题,您的回答无关紧要。 @pferdefleisch @mburn 说得通。已经 3 年了,现在这可能看起来有点不合适或令人讨厌。不过我会保留它,因为对我的评论的赞成票告诉我,至少有几个人可能会觉得它很有用(或者他们只是不喜欢没有 cmets 的反对票)。【参考方案7】:试试这个:
#yourElementId
background: url(yourImageLocation.jpg) no-repeat center center;
width: 100px;
height: 100px;
请记住,width
和 height
仅在您的 DOM 元素具有布局(块显示元素,如 div
或 img
)时才有效。如果不是(例如跨度),请将 display: block;
添加到 CSS 规则中。如果您无权访问 CSS 文件,请将样式内嵌到元素中。
【讨论】:
在大多数情况下,此 CSS 会重复用于不同的图像。因此,将背景图片设置为内联是不可避免的。以上是关于如何自动裁剪和居中图像的主要内容,如果未能解决你的问题,请参考以下文章