Ios 将图像剪成圆形
我想把一个Ios 将图像剪成圆形,ios,swift,uiimage,Ios,Swift,Uiimage,我想把一个UIImage切成一个圆,这样我就可以把它用作注释了。我在这个网站上找到的每一个答案都描述了创建一个UIImageView,然后修改并显示它,但是你不能将注释的图像设置为UIImageView,只有UIImage。 我应该怎么做?如果需要,请确保导入QuarzCore func maskRoundedImage(image: UIImage, radius: CGFloat) -> UIImage { let imageView: UIImageView = U
UIImage
切成一个圆,这样我就可以把它用作注释了。我在这个网站上找到的每一个答案都描述了创建一个UIImageView
,然后修改并显示它,但是你不能将注释的图像设置为UIImageView
,只有UIImage
。
我应该怎么做?如果需要,请确保导入QuarzCore
func maskRoundedImage(image: UIImage, radius: CGFloat) -> UIImage {
let imageView: UIImageView = UIImageView(image: image)
let layer = imageView.layer
layer.masksToBounds = true
layer.cornerRadius = radius
UIGraphicsBeginImageContext(imageView.bounds.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage!
}
我设法通过使用BezierPath来回答我自己的问题
if let xyz = UIImage(contentsOfFile: readPath) {
var Rect: CGRect = CGRectMake(0, 0, xyz.size.width, xyz.size.height)
var x = UIBezierPath(roundedRect: Rect, cornerRadius: 200).addClip()
UIGraphicsBeginImageContextWithOptions(xyz.size, false, xyz.scale)
xyz.drawInRect(Rect)
var ImageNew = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
annotation.image = ImageNew
}
Xcode 11•Swift 5.1或更高版本 编辑/更新:对于iOS10+,我们可以使用UIGraphicsImageRenderer。对于较旧的Swift语法,请检查编辑历史记录
extension UIImage {
var isPortrait: Bool { size.height > size.width }
var isLandscape: Bool { size.width > size.height }
var breadth: CGFloat { min(size.width, size.height) }
var breadthSize: CGSize { .init(width: breadth, height: breadth) }
var breadthRect: CGRect { .init(origin: .zero, size: breadthSize) }
var circleMasked: UIImage? {
guard let cgImage = cgImage?
.cropping(to: .init(origin: .init(x: isLandscape ? ((size.width-size.height)/2).rounded(.down) : 0,
y: isPortrait ? ((size.height-size.width)/2).rounded(.down) : 0),
size: breadthSize)) else { return nil }
let format = imageRendererFormat
format.opaque = false
return UIGraphicsImageRenderer(size: breadthSize, format: format).image { _ in
UIBezierPath(ovalIn: breadthRect).addClip()
UIImage(cgImage: cgImage, scale: format.scale, orientation: imageOrientation)
.draw(in: .init(origin: .zero, size: breadthSize))
}
}
}
操场测试
let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
profilePicture.circleMasked
UIImage扩展名:
扩展UIImage{
func circularImage(大小:CGSize?->UIImage{
让newSize=size×self.size
让minEdge=min(newSize.height,newSize.width)
let size=CGSize(宽度:minEdge,高度:minEdge)
UIGraphicsBeginImageContextWithOptions(大小,false,0.0)
let context=UIGraphicsGetCurrentContext()
self.drawInRect(CGRect(原点:CGPoint.zero,大小:size),blendMode:.Copy,alpha:1.0)
CGContextSetBlendMode(上下文,.Copy)
CGContextSetFillColorWithColor(上下文,UIColor.clearColor().CGColor)
设rectPath=UIBezierPath(rect:CGRect(原点:CGPoint.zero,大小:size))
设circlePath=UIBezierPath(ovalInRect:CGRect(原点:CGPoint.zero,大小:size))
rectPath.appendPath(circlePath)
rectPath.usesevenodfillrule=true
rectPath.fill()
让结果=UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsSendImageContext()
返回结果
}
}
用法:
UIImageView:
@IBDesignable类CircularImageView:UIImageView{
覆盖变量映像:UIImage{
迪塞特{
super.image=图像?.circularImage(大小:零)
}
}
}
UI按钮:
@IBDesignable class CircularImageButton:UIButton{
覆盖func setImage(图像:UIImage?,用于状态:uicontrol状态){
设circularImage=图像?.circularImage(大小:零)
super.setImage(circularImage,forState:state)
}
}
Xcode 8.1,Swift 3.0.1
我的代码如下所示:
let image = yourImage.resize(CGSize(width: 20, height: 20))?.circled(forRadius: 20)
添加UIImage扩展名,然后:
func resize(_ size: CGSize) -> UIImage? {
let rect = CGRect(origin: .zero, size: size)
return redraw(in: rect)
}
func redraw(in rect: CGRect) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext(), let cgImage = cgImage else { return nil }
let rect = CGRect(origin: .zero, size: size)
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: rect.size.height)
context.concatenate(flipVertical)
context.draw(cgImage, in: rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
func circled(forRadius radius: CGFloat) -> UIImage? {
let rediusSize = CGSize(width: radius, height: radius)
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext(), let cgImage = cgImage else { return nil }
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: rect.size.height)
context.concatenate(flipVertical)
let bezierPath = UIBezierPath(roundedRect: rect, byRoundingCorners: [.allCorners], cornerRadii: rediusSize)
context.addPath(bezierPath.cgPath)
context.clip()
context.drawPath(using: .fillStroke)
context.draw(cgImage, in: rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
您可以使用此代码来圈出图像
extension UIImage {
func circleImage(_ cornerRadius: CGFloat, size: CGSize) -> UIImage? {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
if let context = UIGraphicsGetCurrentContext() {
var path: UIBezierPath
if size.height == size.width {
if cornerRadius == size.width/2 {
path = UIBezierPath(arcCenter: CGPoint(x: size.width/2, y: size.height/2), radius: cornerRadius, startAngle: 0, endAngle: 2.0*CGFloat(Double.pi), clockwise: true)
}else {
path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
}
}else {
path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
}
context.addPath(path.cgPath)
context.clip()
self.draw(in: rect)
// 从上下文上获取剪裁后的照片
guard let uncompressedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return nil
}
// 关闭上下文
UIGraphicsEndImageContext()
return uncompressedImage
}else {
return nil
}
}}
swift 3符合MVC模式 创建一个外部文件
@IBDesignable
class RoundImage: UIImageView{
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet{
self.layer.cornerRadius = cornerRadius
}
}
// set border width
@IBInspectable var borderWidth: CGFloat = 0 {
didSet{
self.layer.borderWidth = borderWidth
}
}
// set border color
@IBInspectable var borderColor: UIColor = UIColor.clear {
didSet{
self.layer.borderColor = borderColor.cgColor
}
}
override func awakeFromNib() {
self.clipsToBounds = true
}
}// class
在故事板上的IB中调用类
根据需要设置拐角半径(如果需要圆形,则为宽度的1/2)
完成了 对于一个直接的解决方案来说,所有这些答案都非常复杂。我只是复制了我的Objective-C代码,并根据Swift进行了调整
self.myImageView?.layer.cornerRadius = (self.myImageView?.frame.size.width)! / 2;
self.myImageView?.clipsToBounds = true
根据尼科斯的回答:
public extension UIImage {
func roundedImage() -> UIImage {
let imageView: UIImageView = UIImageView(image: self)
let layer = imageView.layer
layer.masksToBounds = true
layer.cornerRadius = imageView.frame.width / 2
UIGraphicsBeginImageContext(imageView.bounds.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage!
}
}
//Usage
let roundedImage = image.roundedImage()
我使用的是RoundedImageView类,面临的问题是,当从gallery浏览图像时,图像不会以圆形或圆形显示。。我只需更改UIImageView/RoundedImageView->view->Content Mode->Aspect Fill的属性即可Swift 5.3、Xcode 12.2处理所有图像方向 根据答案 谢谢,很好用!但仅适用于具有imageOrientation.up或.down的图像。对于具有.right或.left方向的图像,结果中存在失真。最初我们通过iPhone/iPad相机拍摄原始照片,获得了正确的方位 下面的代码考虑了imageOrientation属性:
extension UIImage {
func cropToCircle() -> UIImage? {
let isLandscape = size.width > size.height
let isUpOrDownImageOrientation = [0,1,4,5].contains(imageOrientation.rawValue)
let breadth: CGFloat = min(size.width, size.height)
let breadthSize = CGSize(width: breadth, height: breadth)
let breadthRect = CGRect(origin: .zero, size: breadthSize)
let xOriginPoint = CGFloat(isLandscape ?
(isUpOrDownImageOrientation ? ((size.width-size.height)/2).rounded(.down) : 0) :
(isUpOrDownImageOrientation ? 0 : ((size.height-size.width)/2).rounded(.down)))
let yOriginPoint = CGFloat(isLandscape ?
(isUpOrDownImageOrientation ? 0 : ((size.width-size.height)/2).rounded(.down)) :
(isUpOrDownImageOrientation ? ((size.height-size.width)/2).rounded(.down) : 0))
guard let cgImage = cgImage?.cropping(to: CGRect(origin: CGPoint(x: xOriginPoint, y: yOriginPoint),
size: breadthSize)) else { return nil }
let format = imageRendererFormat
format.opaque = false
return UIGraphicsImageRenderer(size: breadthSize, format: format).image {_ in
UIBezierPath(ovalIn: breadthRect).addClip()
UIImage(cgImage: cgImage, scale: format.scale, orientation: imageOrientation).draw(in: CGRect(origin: .zero, size: breadthSize))
}
}
}
好吧,我想会的,我只是检查了一下,我已经导入了QuartzCore和所有东西,但没有环绕图像。你能检查一下它是否适用于你吗?是的,我在一个操场上检查过。如果你看到别名图像,请使用
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size,false,UIScreen.mainScreen().scale)
。非常感谢!简单实用的答案!我认为这个代码太复杂了。您可以使用剪切路径直接渲染到图像上下文中,而不是创建未使用的图像视图。太棒了!我已经在这上面呆了一段时间了,谢谢!谢谢圈。你是上帝。@b卡特尔他的方法会扭曲不真实的形象squared@LeoDabus我忘了送赏金了,赏金马上就到。顺便说一句,你的经典答案在这里非常有用:@Fattie Yes Geddy Lee本人:我在寻找将图像裁剪成圆形的代码,我发现这个答案是最好的!,但是有一个问题,图像是反转的,如何修复?你能帮忙吗?嗨@Salah,很抱歉,我以前的方法有一些问题。我已经在我的代码中修复了这个问题,你可以试试!但是,虽然我必须编写圈(:)
方法,但我很少使用它。大多数情况下,resize
+`fill(with:)`方法将帮助我控制我的资产图像,我向您推荐Kingfisher
,他必须提供`roundcorneimageprocessor`此类来执行图像裁剪功能。你可以在这里看到(.@Salah我写了一篇英语来展示我所有的图像助手。我非常欢迎你学习iOS开发。你可以在gist.github.com/YueJun1991/867f667f5a14eb65deaacf9db2120481中看到这一点。非常感谢你!我很感激这真的很有帮助,我使用了你的新图片,并用圆圈圈出,但图片仍然颠倒了。它看起来像这样:为什么会发生这种情况g?我无法修复它。我需要使用contentMode=.scaleAspectFit
为UIImageView设置圆形图像。这个答案非常有效。如果有很多这样的项目,使用层角半径可能会导致掉帧/性能问题。这就是为什么会有更复杂的替代解决方案