ios 舍入 UIImage 并添加边框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34984966/
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
Rounding UIImage and adding a border
提问by Olexiy Burov
so I want to show some pictures as annotations on the map. In order to do that I need to add the image property of the MKAnnotationView. I'm using the regular images but I want them to be rounded and with a border. So I found a way to round UIImage and I found the way to add a border to UIImage, but border doesn't seem to add (I'm not actually having the image on the screen, maybe that is the problem?).
所以我想在地图上显示一些图片作为注释。为此,我需要添加 MKAnnotationView 的图像属性。我正在使用常规图像,但我希望它们是圆形的并带有边框。所以我找到了一种绕过 UIImage 的方法,我找到了向 UIImage 添加边框的方法,但边框似乎没有添加(我实际上没有在屏幕上显示图像,也许这就是问题所在?)。
I used this answer https://stackoverflow.com/a/29047372/4665643with a slight modification for border. Namely:
我使用了这个答案https://stackoverflow.com/a/29047372/4665643对边框稍作修改。即:
imageView.layer.borderWidth = 1.5
imageView.layer.borderColor = UIColor.whiteColor().CGColor
imageView.clipsToBounds = true
But my image on the map doesn't have any border. Any suggestions ?
但是我在地图上的图像没有任何边框。有什么建议 ?
回答by keval
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 1.5
imageView.layer.borderColor = UIColor.white.cgColor
imageView.layer.cornerRadius = imageView.bounds.width / 2
Try this.
尝试这个。
回答by Leo Dabus
If you would like to add a border to your image you need to make sure you add some extra room to it otherwise your border will be placed in top of your image. The solution is to add twice the width of your stroke to your image's width and height.
如果您想为图像添加边框,您需要确保为其添加一些额外的空间,否则您的边框将放置在图像的顶部。解决方案是将笔画宽度的两倍添加到图像的宽度和高度。
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) }
func rounded(with color: UIColor, width: CGFloat) -> UIImage? {
let bleed = breadthRect.insetBy(dx: -width, dy: -width)
UIGraphicsBeginImageContextWithOptions(bleed.size, false, scale)
defer { UIGraphicsEndImageContext() }
guard let cgImage = cgImage?.cropping(to: CGRect(origin: CGPoint(
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 }
UIBezierPath(ovalIn: .init(origin: .zero, size: bleed.size)).addClip()
var strokeRect = breadthRect.insetBy(dx: -width/2, dy: -width/2)
strokeRect.origin = .init(x: width/2, y: width/2)
UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation)
.draw(in: strokeRect.insetBy(dx: width/2, dy: width/2))
color.set()
let line: UIBezierPath = .init(ovalIn: strokeRect)
line.lineWidth = width
line.stroke()
return UIGraphicsGetImageFromCurrentImageContext()
}
}
For iOS10+ We can use UIGraphicsImageRenderer.
对于 iOS10+ 我们可以使用 UIGraphicsImageRenderer。
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) }
func rounded(with color: UIColor, width: CGFloat) -> UIImage? {
guard let cgImage = cgImage?.cropping(to: .init(origin: .init(x: isLandscape ? ((size.width-size.height)/2).rounded(.down) : .zero, y: isPortrait ? ((size.height-size.width)/2).rounded(.down) : .zero), size: breadthSize)) else { return nil }
let bleed = breadthRect.insetBy(dx: -width, dy: -width)
let format = imageRendererFormat
format.opaque = false
return UIGraphicsImageRenderer(size: bleed.size, format: format).image { context in
UIBezierPath(ovalIn: .init(origin: .zero, size: bleed.size)).addClip()
var strokeRect = breadthRect.insetBy(dx: -width/2, dy: -width/2)
strokeRect.origin = .init(x: width/2, y: width/2)
UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation)
.draw(in: strokeRect.insetBy(dx: width/2, dy: width/2))
context.cgContext.setStrokeColor(color.cgColor)
let line: UIBezierPath = .init(ovalIn: strokeRect)
line.lineWidth = width
line.stroke()
}
}
}
Playground Testing:
游乐场测试:
let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
let pp = profilePicture.rounded(with: .red, width: 10)
回答by Arun Ammannaya
Use this extension to UIImageView :
将此扩展用于 UIImageView :
func cropAsCircleWithBorder(borderColor : UIColor, strokeWidth: CGFloat)
{
var radius = min(self.bounds.width, self.bounds.height)
var drawingRect : CGRect = self.bounds
drawingRect.size.width = radius
drawingRect.origin.x = (self.bounds.size.width - radius) / 2
drawingRect.size.height = radius
drawingRect.origin.y = (self.bounds.size.height - radius) / 2
radius /= 2
var path = UIBezierPath(roundedRect: CGRectInset(drawingRect, strokeWidth/2, strokeWidth/2), cornerRadius: radius)
let border = CAShapeLayer()
border.fillColor = UIColor.clearColor().CGColor
border.path = path.CGPath
border.strokeColor = borderColor.CGColor
border.lineWidth = strokeWidth
self.layer.addSublayer(border)
path = UIBezierPath(roundedRect: drawingRect, cornerRadius: radius)
let mask = CAShapeLayer()
mask.path = path.CGPath
self.layer.mask = mask
}
Usage :
用法 :
self.circleView.cropAsCircleWithBorder(UIColor.redColor(), strokeWidth: 20)
Result :
结果 :
回答by Rajat
For making an image rounded with border, you can do that from User Defined Runtime Attributes also, no need to write code for that.
要制作带有边框的圆形图像,您也可以从用户定义的运行时属性中执行此操作,无需为此编写代码。
Please check the below image for setting that
请检查下图进行设置
Also in your code, change
同样在您的代码中,更改
imageView.layer.clipsToBounds = true
to this,
对此,
imageView.layer.masksToBounds = true
回答by coldembrace
Leo Dabus's solution in Swift 3:
Leo Dabus在 Swift 3 中的解决方案:
extension UIImage {
func roundedImageWithBorder(width: CGFloat, color: UIColor) -> UIImage? {
let square = CGSize(width: min(size.width, size.height) + width * 2, height: min(size.width, size.height) + width * 2)
let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: square))
imageView.contentMode = .center
imageView.image = self
imageView.layer.cornerRadius = square.width/2
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = width
imageView.layer.borderColor = color.cgColor
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
imageView.layer.render(in: context)
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
回答by Anand
simple one line code its works for me
简单的一行代码对我有用
self.profileImage.layer.cornerRadius = self.profileImage.frame.size.width / 2
回答by Olexiy Burov
Just fixed it. Apparently everything was working perfectly but I wasn't seeing the border. The original image is about 300x300 pixels and with 1.5 pixel border I was cropping it to fit 40x40 frame so the border was barely noticeable. Changing border width to a bigger number made it visible.
刚修好。显然一切正常,但我没有看到边界。原始图像约为 300x300 像素,边框为 1.5 像素,我将其裁剪为适合 40x40 帧,因此边框几乎不明显。将边框宽度更改为更大的数字使其可见。