Cómo recortar y centrar automáticamente una imagen

159

Dada cualquier imagen arbitraria, quiero recortar un cuadrado desde el centro de la imagen y mostrarlo dentro de un cuadrado determinado.

Esta pregunta es similar a esta: CSS muestra una imagen redimensionada y recortada , pero no sé el tamaño de la imagen, así que no puedo usar los márgenes establecidos.

Jonathan Ong
fuente
1
¿El elemento debe ser una etiqueta de imagen, o puede ser un div con una propiedad de imagen de fondo?
Russ Ferri
mientras pueda configurar la imagen a través de mi sistema de plantillas, no importa. un poco feo, pero supongo que los estilos en línea funcionarán.
Jonathan Ong

Respuestas:

319

Una solución es usar una imagen de fondo centrada dentro de un elemento dimensionado a las dimensiones recortadas.


Ejemplo básico

.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>


Ejemplo con imgetiqueta

Esta versión conserva la imgetiqueta para que no perdamos la capacidad de arrastrar o hacer clic derecho para guardar la imagen. Gracias a Parker Bennett por el truco de la opacidad.

.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

Ver navegadores compatibles .

La especificación de Imágenes CSS3 define las propiedades object-fity object-positionque juntas permiten un mayor control sobre la escala y la posición del contenido de la imagen de un imgelemento. Con estos, será posible lograr el efecto deseado:

.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" />

Russ Ferri
fuente
45
Puede usar background-size: cover;para hacer que la imagen se reduzca o llene el div de manera apropiada mientras mantiene la relación de aspecto original.
Nick
77
Al usar background-image, debe agregar background-size: cover para dimensionar adecuadamente la imagen recortada: consulte jsfiddle.net/bw6ct
Kris Erickson
2
Me han dicho que hoy en día Google conoce las imágenes transparentes y ocultas, por lo que imglos atributos de las althormigas titlese perderán para su SEO.
Victor Sergienko
66
en webkit también puede usar object-fit: cover;directamente en la etiqueta img que se siente un poco más semántica.
Ben
2
Utilicé Object-Fit: Cover para obtener el efecto deseado de no perder la relación de aspecto, cubrir el cuadrado y recortar si es necesario
Daniel Handojo
79

Estaba buscando una solución CSS pura usando imgetiquetas (no la imagen de fondo).

Encontré esta forma brillante de lograr el objetivo en miniaturas de recorte con 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;
}

Es similar a la respuesta de @Nathan Redblur, pero también permite imágenes de retratos.

Funciona como un encanto para mí. Lo único que necesita saber sobre la imagen es si es vertical u horizontal para establecer la .portraitclase, por lo que tuve que usar un poco de Javascript para esta parte.

gluecksmelodie
fuente
3
Solo tenga en cuenta que las transformaciones CSS solo están disponibles en IE 9 y superior.
Simon East
55
Esta debería ser la respuesta.
Wes Modes
OP dijo "imagen arbitraria", por lo que no sabría por adelantado si la imagen era más alta que ancha.
opiato
11
Si pone min-height: 100%; min-width: 100%; en lugar de altura: 100%; ancho: automático; no necesitas la clase img.portrait.
user570605
1
mejor solución combinada con la sugerencia @ user570605
albanx
45

Pruebe esto: establezca las dimensiones de recorte de su imagen y use esta línea en su CSS:

object-fit: cover;
Roych
fuente
3
no muy bien soportado: caniuse.com/#feat=object-fit EDIT: en realidad, como de costumbre, solo los navegadores MS fallan en esto ... aunque representa una gran parte del uso: /
Brian H.
1
Esto hace exactamente lo que necesito :)
hcarreras
1
Los únicos navegadores ampliamente utilizados que no admiten esto son Internet Explorer 11 y Edge. Dependiendo de su audiencia, el soporte en este momento probablemente sea de alrededor del 85-90%, lo que podría hacer que esto sea viable para algunos escenarios.
Husky
¡Rey! ¡Una solución increíble!
itzhar
1
hay un buen tutorial sobre eso: medium.com/@chrisnager/…
Pietro La Grotta
23

Ejemplo con imgetiqueta pero sinbackground-image

Esta solución retiene la imgetiqueta para que no perdamos la capacidad de arrastrar o hacer clic con el botón derecho para guardar la imagen, pero sin background-imagesimplemente centrar y recortar con CSS.

Mantenga la relación de aspecto bien, excepto en imágenes muy altas. (verifique el enlace)

(ver en acción)

Margen

<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%);
}
Nathan Redblur
fuente
Pruebe este ... si la imagen es más pequeña que el contenedor que centrará, de lo contrario se recortará jsfiddle.net/3ts4rm24/1
KnF
8

Creé una directiva angularjs usando las respuestas de @ Russ y @ Alex

Podría ser interesante en 2014 y más allá: 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 + "')");
          }
      }
  });

enlace de violín

mraaroncruz
fuente
3
Hola, downvoters. Por favor, deje un comentario para que pueda actualizar mi respuesta si hay un error. No me gusta dar información falsa. Salud.
mraaroncruz
No es un votante negativo, pero esta no es una pregunta angular y su respuesta es irrelevante. @pferdefleisch
mawburn
1
@Burn que tiene sentido. Han pasado 3 años y esto probablemente parece un poco fuera de lugar o desagradable ahora. Sin embargo, lo dejaré porque los votos positivos en mi comentario me dicen que al menos un par de personas pueden encontrarlo útil (o simplemente no les gustan los votos negativos sin comentarios).
mraaroncruz
2

Prueba esto:

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

Tenga en cuenta que widthy heightsólo funcionará si su elemento DOM tiene la disposición (elemento de un bloque de muestra, como un divo una img). Si no lo es (un lapso, por ejemplo), agréguelo display: block;a las reglas CSS. Si no tiene acceso a los archivos CSS, suelte los estilos en línea en el elemento.

Alejandro Rizzo
fuente
en la mayoría de los casos, este CSS se usa repetidamente con diferentes imágenes. por lo tanto, es inevitable establecer la imagen de fondo en línea.
Raptor
0

Hay otra forma de recortar la imagen centrada:

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

Lo único que necesitará es agregar la clase "vertical" a las imágenes verticales, puede hacerlo con este código:

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

Nota: "! Important" se usa para anular posibles atributos de ancho y alto en la etiqueta img.

Vedmant
fuente