如何自动裁剪和居中图像


158

给定任意图像,我想从图像中心裁剪一个正方形并将其显示在给定的正方形内。

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


1
元素必须是图像标签,还是可以是具有background-image属性的div?
罗斯·费里

只要我可以通过模板系统设置图像,就没关系。有点丑陋,但是我想内联样式会起作用。
乔纳森·翁

Answers:


318

一种解决方案是使用以元素大小为裁剪尺寸的元素为中心的背景图像。


基本例子

.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标签,因此我们不会失去拖动或右键单击以保存图像的功能。信贷帕克贝内特不透明度伎俩。

.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

请参阅支持的浏览器

CSS3图像规范定义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="http://placehold.it/200x200" />


45
您可以用来background-size: cover;保持原始纵横比的同时适当缩小或填充div的图像。
尼克

7
使用background-image时,您应该添加background-size:cover来适当调整裁剪图像的大小:请参阅jsfiddle.net/bw6ct
Kris Erickson

2
有人告诉我,如今Google知道透明和隐藏的图像,因此您的SEO imgaltant title属性将丢失。
Victor Sergienko 2014年

6
在webkit中,您还可以object-fit: cover;直接在img标签上使用,这会带来更多语义。
2014年

2
我使用了对象适配:遮盖以获得我想要的效果,即不失去长宽比,遮盖正方形并在需要时进行裁剪
Daniel Handojo

79

我一直在寻找使用img标签的纯CSS解决方案(而不是背景图片)。

我发现这种出色的方法可以通过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。


3
请注意,CSS转换仅在IE 9及更高版本中可用。
西蒙东

5
这应该是答案。
Wes模式

OP表示“任意图像”,因此如果图像的高度大于宽度,则不会预先知道。
2016年

11
如果您输入min-height:100%; min-width:100%; 而不是height:100%; width:auto; 您不需要img.portrait类。
2016年

1
最佳解决方案并结合@ user570605建议
albanx

45

尝试以下操作:设置图像裁剪尺寸,并在CSS中使用以下行:

object-fit: cover;

3
不太受支持:caniuse.com/#feat=object-fit编辑:实际上,像往常一样,只是MS浏览器在此上失败了...虽然确实代表了很大一部分用法:/
Brian H.

1
这正是我需要的:)
hcarreras

1
唯一不支持此功能的浏览器是Internet Explorer 11和Edge。根据您的听众的不同,现在的支持率可能约为85-90%,这在某些情况下可能可行。
赫斯基

国王!很棒的解决方案!!
itzhar

1
疗法是关于一个很好的教程:medium.com/@chrisnager/...
彼得香格里拉格罗

23

img标签但不带标签的示例background-image

该解决方案保留了img标签,因此我们不会失去拖动或右键单击以保存图像的能力,而background-image不仅仅是使用CSS居中和裁剪。

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

(观看中)

标记

<div class="center-cropped">
    <img src="http://placehold.it/200x150" alt="" />
</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
KnF 2015年

8

我使用@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 + "')");
          }
      }
  });

小提琴链接


3
Hiya投票者。请发表评论,以便在出现错误时更新我的​​答案。我不喜欢提供虚假信息。干杯。
mraaroncruz

不是拒绝投票的人,但这不是一个Angular问题,您的答案无关紧要。@pferdefleisch
mawburn

1
@mburn很有道理。已有3年了,现在看起来可能有点不合时宜或令人讨厌。不过,我将其保留,因为我的评论中的赞成票告诉我至少有几个人可能会觉得有用(或者他们只是不喜欢无评论的赞成票)。
mraaroncruz

2

试试这个:

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

请记住,width并且height仅在您的DOM元素具有布局(显示为块的元素,如a div或an img)时才有效。如果不是(例如,一个跨度),则添加display: block;到CSS规则。如果您无权访问CSS文件,请在元素中内联样式。


在大多数情况下,此CSS会与不同的图像重复使用。因此,不可避免地将背景图像设置为内联。
猛禽

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

您唯一需要做的就是将“垂直”类添加到垂直图像中,您可以使用以下代码进行操作:

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标签上可能的宽度,高度属性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.