如何自动裁剪并居中一张图片?

191

对于任意的图片,我想从图片中央裁剪一个正方形,并在给定的正方形内显示它。

这个问题与此类似:CSS 显示已调整大小并裁剪的图像,但是我不知道图片的大小,因此无法使用设置边距的方法。


1
该元素必须是图像标记吗?还是可以是具有背景图像属性的div呢? - Russ Ferri
只要我可以通过我的模板系统设置图像,那就没关系。虽然有点丑,但我想内联样式会起作用。 - Jonathan Ong
9个回答

372
一种解决方案是使用一个背景图片,将其居中放置在一个尺寸为裁剪尺寸的元素内。

基本示例

.center-cropped {
  width: 100px;
  height: 100px;
  background-position: center center;
  background-repeat: no-repeat;
}
<div class="center-cropped" 
     style="background-image: url('https://via.placeholder.com/200');">
</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('https://via.placeholder.com/200');">
  <img src="https://via.placeholder.com/200" />
</div>


object-fit/-position

请参见支持的浏览器

CSS3 Images specification定义了object-fitobject-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="https://via.placeholder.com/200" />


54
您可以使用background-size: cover;属性来自适应地缩小或填充div,同时保持原始宽高比。 - Nick
7
使用background-image时,应该添加background-size: cover来正确调整裁剪后的图片大小:请见http://jsfiddle.net/bw6ct/ - Kris Erickson
2
我听说现在Google知道透明和隐藏的图片,所以imgalttitle属性将会对你的SEO产生影响。 - Victor Sergienko
8
在 WebKit 中,你也可以直接在 img 标签上使用 object-fit: cover;,这样会更符合语义。 - Ben
2
我使用了 object-fit: cover 来实现我的期望效果,即不失去宽高比,覆盖正方形,并在需要时进行裁剪。 - Daniel Handojo
显示剩余5条评论

90

3
请注意,CSS变换仅在IE 9及以上版本中可用。 - Simon East
6
这应该就是答案。 - Wes Modes
1
OP说“任意图像”,因此无法事先知道图像是高还是宽。 - opyate
12
如果您将height:100%;width:auto;替换为min-height:100%;min-width:100%;,则无需使用img.portrait类。 - user570605
1
最佳解决方案结合@user570605的建议。 - albanx
在WordPress中,您还需要将max-width: none;添加到.thumbnail img - Slam

69
尝试这个:设置你的图片裁剪尺寸并在CSS中使用这行代码:

设置你的图片裁剪尺寸并在CSS中使用这行代码:

object-fit: cover;

3
支持不太好:http://caniuse.com/#feat=object-fit。更新:实际上,像往常一样,只有微软浏览器不支持这个特性... 不过它仍然占据相当大的使用量:/ - Brian H.
1
这正好满足我的需求 :) - hcarreras
1
唯一广泛使用但不支持此功能的浏览器是Internet Explorer 11和Edge。根据您的受众,目前的支持率可能在85-90%左右,这可能使其在某些情况下可行。 - Husky
1
这方面有一个不错的教程:https://medium.com/@chrisnager/center-and-crop-images-with-a-single-line-of-css-ad140d5b4a87 - Pietro La Grotta
1
2021年效果非常好。 - kennydust
显示剩余2条评论

24

img 标签但没有 background-image 的示例

这个解决方案保留了 img 标签,因此我们不会失去拖动或右键保存图像的能力,但是没有使用 background-image,只使用 CSS 进行居中和裁剪。

保持宽高比良好,除非是非常高的图像。(请查看链接)

(查看实际效果)

标记

<div class="center-cropped">
    <img src="http://placehold.it/200x150" alt="" />
</div>

CSS

翻译后为:

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%);
}

试试这个...如果图像比容器小,它将居中,否则它将裁剪 http://jsfiddle.net/3ts4rm24/1/ - KnF
为什么要在 transform: translateX(-50%) 中使用 left: 50% - Oleg Yablokov
left 是与容器相关的位置 translate 是与元素相关的 如果您的容器为100px,而您的图片为20px,则 left 将把图片放置在50px-70px的位置之间。为了解决这个问题,我们使用 translateX(-50%) 来重置图片的大小,然后您的图片将位于40px-60px之间。 例如:如果您的容器为100px,则 left: 50% 表示该容器的中心位置rightMiddle = 容器/2 - 元素/2 - Nathan Redblur

9

我使用@Russ和@Alex的答案创建了一个angularjs指令。

这在2014年及以后可能会很有趣 :P

html

<div ng-app="croppy">
  <cropped-image src="http://placehold.it/200x200" width="100" height="100"></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


4
各位给我下投票的朋友们,如果我的回答有错误,请留言告诉我,这样我就可以进行更新了。我不喜欢提供虚假信息。谢谢。 - mraaroncruz
不是恶评者,但这不是一个Angular问题,你的回答是无关的。@pferdefleisch - mawburn
1
@mburn,这很有道理。现在已经过去了3年,这可能看起来有点不合时宜或讨厌。不过我还是会保留它,因为我的评论上的赞告诉我至少有几个人可能会觉得它有用(或者他们只是不喜欢没有评论的踩)。 - mraaroncruz

2
尝试这个:
#yourElementId
{
    background: url(yourImageLocation.jpg) no-repeat center center;
    width: 100px;
    height: 100px;
}

请记住,只有当您的DOM元素具有布局(块显示元素,如

)时,widthheight才能起作用。如果不是(例如span),请在CSS规则中添加display:block;。如果您无法访问CSS文件,请将样式内联到元素中。


在大多数情况下,这个CSS会被重复使用,并且会与不同的图片一起使用。因此,将背景图片设置为内联是不可避免的。 - Raptor

0

还有另一种方法可以将图像居中裁剪:

.thumbnail{position: 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.vertical{width: 100% !important; height: auto !important;}

唯一需要做的就是将类名“vertical”添加到垂直图片中,您可以使用以下代码实现:
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 标签上可能存在的宽度、高度属性。

0

如果要像Instagram探索或网格一样使用,请在img标签上使用此代码

aspect-ratio: 1 / 1; //or whatever
object-fit: cover;

请注意,父元素必须具有网格显示


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Dhaval Purohit

0

最好的两个世界,一些调整大小和一些裁剪,通过双 flexbox 围绕图像。适用于全屏图像(我将其用于图像轮播)。容器的宽度:100vw 和高度:100vh 是魔法 CSS。

HTML:

<div class="container">
   <div class="slide">
   <img src="https://someimageurl.jpg" 
   alt="image" class="image">
   </div>
</div>

CSS:

  .container {
  display: flex;
  position: relative;
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
  justify-items: center;
  justify-content: center;
  }
 
 .slide {
 display: flex;
 width: 100%;
 height: 100%;
 max-width: 1600px;
 max-height: 1000px;
 justify-items: center;
 justify-content: center;
 margin: auto;
 padding: 0;
 overflow: hidden;
 }
 
 .image {
 display: block;
 min-width: 100%;
 min-height: 100%;
 object-fit: cover; /* Cover the image */
 object-position: center;
 margin: auto;
 padding: 0;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接