将图像裁剪为正方形,然后使用纯 CSS 进行圆形?

Posted

技术标签:

【中文标题】将图像裁剪为正方形,然后使用纯 CSS 进行圆形?【英文标题】:Crop image into square and then to circle using pure CSS? 【发布时间】:2017-08-13 06:36:53 【问题描述】:

我正在尝试用不同大小和不同形状(一些矩形、一些正方形、一些肖像、一些风景)的图像制作一个圆形。

当我使用:clip-path: circle(50% at 50% 50%);border-radius: 50%; 时,它会将图像变成一个完美的圆形,如果图像是方形的:

有没有办法将图像裁剪成正方形,然后使用其中一种方法使其成为完美的圆形:

    使用纯 CSS 不使用 background-image(大多数图片都是从服务器端获得的背景图片), 保持 50% 的比例 - 不损失纵横比 - (border-radiusclip-path)(图片大小可能会有所不同)。

这是一个代码 sn-p 来显示一个正方形图像和一个矩形图像:

.clipped 
    clip-path: circle(50% at 50% 50%);
Square<br>
<img src='http://i.imgur.com/d5byNNR.jpg'  class='clipped' /><br><br>
Rectangle<br>
<img src='http://i.imgur.com/22W12EQ.jpg'  class='clipped' />

【问题讨论】:

顺便说一句,这是我女儿的照片,所以版权归我所有! :) 你说有没有办法把图片变成正方形。您是说可以将矩形图像调整为正方形并丢失图像的纵横比吗? @FrankFajardo 不丢失纵横比 - 将其裁剪成正方形。 只使用clip-path: circle(); 似乎有效。它将图像裁剪为一个圆形,并使用较小的一侧作为圆周。但它显然只保留了图像的中心部分。 @FrankFajardo Groovy。请将此作为答案发布。 【参考方案1】:

你可以使用circle()但不带参数:

.clipped 
   clip-path: circle();

它似乎使用图像的较小边作为圆的圆周。

工作样本here。

它适用于 Chrome 和 FireFox。 IE和Edge仍然不支持clip-path

【讨论】:

只是添加注释clip-path at this stage is considered experimental technology by MDN; so it may change in the future。 感谢您的回答。有没有办法通过 CSS 为 IE 做到这一点? 不是没有 JS。【参考方案2】:

这是另一种使用纯 CSS 的方法:

HTML

<div class="circular--portrait">
  <img src='http://i.imgur.com/22W12EQ.jpg'/>
</div>

CSS

.circular--portrait 
  position: relative;
  overflow: hidden;
  width: 100px;
  height: 100px;
  border-radius: 50%;


.circular--portrait img 
  width: 100%;
  height: auto;
  margin-top: -30px;

Code Snippet (with portrait and landscape examples)

【讨论】:

感谢您的回答。在您提供的 sn-p 中,您能看到图像丢失率吗?它被扭曲了。 谢谢亚历克斯。对该建议投了赞成票。 为什么要添加这个? margin-top: -30px;【参考方案3】:

好吧,花了我一点时间,但这是我想出的:

function ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox, xOffSet, yOffSet) 

	var result =  width: 0, height: 0, fScaleToTargetWidth: true ;

	if ((srcwidth <= 0) || (srcheight <= 0) || (targetwidth <= 0) || (targetheight <= 0)) 
		return result;
	

	// scale to the target width
	var scaleX1 = targetwidth;
	var scaleY1 = (srcheight * targetwidth) / srcwidth;

	// scale to the target height
	var scaleX2 = (srcwidth * targetheight) / srcheight;
	var scaleY2 = targetheight;

	// now figure out which one we should use
	var fScaleOnWidth = (scaleX2 > targetwidth);
	if (fScaleOnWidth) 
		fScaleOnWidth = fLetterBox;
	
	else 
	   fScaleOnWidth = !fLetterBox;
	

	if (fScaleOnWidth) 
		result.width = Math.floor(scaleX1);
		result.height = Math.floor(scaleY1);
		result.fScaleToTargetWidth = true;
	
	else 
		result.width = Math.floor(scaleX2);
		result.height = Math.floor(scaleY2);
		result.fScaleToTargetWidth = false;
	
	//result.targetleft = Math.floor((targetwidth - result.width) / 2);
	//result.targettop = Math.floor((targetheight - result.height) / 2);

	result.targetleft = Math.floor((targetwidth - result.width) / 2 - xOffSet);
	result.targettop = Math.floor((targetheight - result.height) / 2 - yOffSet);

	return result;


function OnImageLoad(evt, xOffSet = 0, yOffSet = 0) 

	var img = evt.currentTarget;

	// what's the size of this image and it's parent
	var w = $(img).width();
	var h = $(img).height();
	var tw = $(img).parent().width();
	var th = $(img).parent().height();

	// compute the new size and offsets
	var result = ScaleImage(w, h, tw, th, false, xOffSet, yOffSet);

	// adjust the image coordinates and size
	img.width = result.width;
	img.height = result.height;
	$(img).css("left", result.targetleft);
	$(img).css("top", result.targettop);
.result 
  width: 250px;
  height: 250px;
  border: thick solid #666666;
  overflow: hidden;
  position: relative;
  border-radius: 50%;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
No offset:
<div class='result'>
	<img src="http://i.imgur.com/22W12EQ.jpg" style="position: absolute;" onload="OnImageLoad(event, 0, 0);"/>
</div>
Y offset:
<div class='result'>
	<img src="http://i.imgur.com/22W12EQ.jpg" style="position: absolute;" onload="OnImageLoad(event, 0, 30);"/>
</div>

我从该资源中获取了大部分工作:https://selbie.wordpress.com/2011/01/23/scale-crop-and-center-an-image-with-correct-aspect-ratio-in-html-and-javascript/,并且我已经熟练地使用它来允许使用偏移,因此您可以在所需的位置裁剪任何图像。

工作原理 您可以创建一个任意大小的 div。它可以是方形的,但如果你想要一个类似鸡蛋的结果,那也可以(笑)。然后在其中插入任意大小未知的图片。

用你想要的偏移量改变onload="OnImageLoad(event, 0, 30);。向左或向下移动图像的正偏移,向上或向右移动的负偏移。

注意:我确实为此使用了 jQuery。

【讨论】:

美丽的帖子。我将实施它,看看它如何违背弗兰克法哈多的建议。无论如何 +1 投票。 @KobyDouek 很高兴为您提供一个适用于所有浏览器的替代方案 :) @KobyDouek Ye 正如我在最后所说:我已经使用了 jQuery。只需将 &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"&gt;&lt;/script&gt; 添加到您的 html 中(在上面的 javascript 之前),它应该可以正常工作:) 不,我知道,但是您在 SO 的 sn-p 出现了错误,我猜您对其进行了编辑然后修复了它。现在一切都很好。谢谢。 @KobyDouek 嗯,我没有解决任何问题。也许是一个小问题?不管怎样,很高兴它现在成功了

以上是关于将图像裁剪为正方形,然后使用纯 CSS 进行圆形?的主要内容,如果未能解决你的问题,请参考以下文章

将不同大小的四边形图像批量裁剪为圆形

如何使用 CSS 居中和裁剪图像以始终以方形显示?

如何将圆形裁剪功能添加到此 UIImagePickerController,目前它显示为正方形

CSS 将横向裁剪为正方形

纯css3制作旋转太极图案

将图像/可绘制对象裁剪为三角形