ios 将 UIImage 剪成圆形
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29046571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cut a UIImage into a circle
提问by Learnin
I want to cut a UIImage
into a circle so that I can then use it as an annotation. Every answer on this site that I've found describes creating an UIImageView
, then modifying that and displaying it, but you cant set the image of an annotation to an UIImageView
, only a UIImage
.
How should I go about this?
我想将 aUIImage
切成一个圆圈,以便我可以将其用作注释。在这个网站每一个答案,我发现描述了创建UIImageView
,然后修改并显示它,但你不能注释的图像设置为UIImageView
,只有一个UIImage
。我应该怎么做?
回答by Leo Dabus
Xcode 11 ? Swift 5.1 or later
Xcode 11?Swift 5.1 或更高版本
edit/update: For iOS10+ We can use UIGraphicsImageRenderer. For older Swift syntax check edit history.
编辑/更新:对于 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: 1, orientation: imageOrientation)
.draw(in: .init(origin: .zero, size: breadthSize))
}
}
}
Playground Testing
游乐场测试
let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
profilePicture.circleMasked
回答by Nikos M.
Make sure to import QuarzCore if needed.
如果需要,请确保导入 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!
}
回答by Dmitry Coolerov
UIImage extension:
UIImage 扩展:
extension UIImage {
func circularImage(size size: CGSize?) -> UIImage {
let newSize = size ?? self.size
let minEdge = min(newSize.height, newSize.width)
let size = CGSize(width: minEdge, height: minEdge)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
self.drawInRect(CGRect(origin: CGPoint.zero, size: size), blendMode: .Copy, alpha: 1.0)
CGContextSetBlendMode(context, .Copy)
CGContextSetFillColorWithColor(context, UIColor.clearColor().CGColor)
let rectPath = UIBezierPath(rect: CGRect(origin: CGPoint.zero, size: size))
let circlePath = UIBezierPath(ovalInRect: CGRect(origin: CGPoint.zero, size: size))
rectPath.appendPath(circlePath)
rectPath.usesEvenOddFillRule = true
rectPath.fill()
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
Usage:
用法:
UIImageView:
UIImageView:
@IBDesignable class CircularImageView: UIImageView {
override var image: UIImage? {
didSet {
super.image = image?.circularImage(size: nil)
}
}
}
UIButton:
界面按钮:
@IBDesignable class CircularImageButton: UIButton {
override func setImage(image: UIImage?, forState state: UIControlState) {
let circularImage = image?.circularImage(size: nil)
super.setImage(circularImage, forState: state)
}
}
回答by Bas
Based on Nikos answer:
基于 Nikos 的回答:
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()
回答by Arco
Xcode 8.1, Swift 3.0.1
Xcode 8.1,Swift 3.0.1
My code will look like this:
我的代码将如下所示:
let image = yourImage.resize(CGSize(width: 20, height: 20))?.circled(forRadius: 20)
Add UIImage Extension, then:
添加 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
}
回答by ParadiseDuo
You can use this code to circle 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
}
}}
回答by Steven Sykes
All these answers were really complex for a straight forward solution. I just replicated my Objective-C code and adjusted for Swift.
对于一个直接的解决方案来说,所有这些答案都非常复杂。我只是复制了我的 Objective-C 代码并针对 Swift 进行了调整。
self.myImageView?.layer.cornerRadius = (self.myImageView?.frame.size.width)! / 2;
self.myImageView?.clipsToBounds = true
回答by Learnin
I managed to answer my own question by finding a use of BezierPath!
我设法通过找到 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
}
回答by alpha911
swift 3 conform to MVC pattern create an external file
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
call class in the IB on storyboard
在故事板上的 IB 中调用类
set cornerradius as you please (1/2 of width if desire circle)
随意设置角半径(如果需要圆形,则为宽度的 1/2)
Done!
完毕!
回答by Maaz Siddiqui
I am using RoundedImageView class, the problem facing is that when browse image from gallery the image not show in round or circle.. I simply change the properties of UIImageView/RoundedImageView -> view -> Content Mode -> Aspect Fillsee screenshot
我使用RoundedImageView类,面临的问题是,当从画廊浏览图像的图像不圆或圆弧显示..我只是改变的UIImageView / RoundedImageView的属性- >查看- >内容模式- >纵横填见截图