I'm trying to create thumbnail images with rounded corners and with a bar at the bottom of the image on iOS.
And I have the following code:
extension UIImage {
func thumbnails(with options: SomeDrawingOptions) -> UIImage? {
// ...
UIGraphicsBeginImageContextWithOptions(targetRect.size, false, 0)
defer {
UIGraphicsEndImageContext()
}
let context = UIGraphicsGetCurrentContext()!
UIColor.white.setFill()
context.fill(targetRect)
UIBezierPath(roundedRect: targetRect, cornerRadius: 8).addClip()
// Drawing image
draw(in: targetRect)
// Drawing a transparent mask
UIColor.black.withAlphaComponent(0.4).setFill()
context.fill(targetRect)
// Drawing bar
UIColor.white.setFill()
context.fill(someBarRect)
return UIGraphicsGetImageFromCurrentImageContext()
}
}
Finally I've got an image with sharp rounded corners just like those in the following snapshot.
Any advise to eliminate the sawtooth of rounded corners?
======= Solution added ======
Thanks the answer for @wj2061, the problem solved. And here is the code:
extension UIImage {
func thumbnails(with options: SomeDrawingOptions) -> UIImage? {
// ...
let targetRect = options.targetRect
let clippedPath = UIBezierPath(roundedRect: targetRect, cornerRadius: 8)
func makeImage() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(targetRect.size, false, 0)
defer { UIGraphicsEndImageContext() }
let context = UIGraphicsGetCurrentContext()!
draw(in: targetRect)
// Drawing a transparent mask
UIColor.black.withAlphaComponent(0.4).setFill()
context.fill(targetRect)
// Drawing bar
UIColor.white.setFill()
context.fill(someBarRect)
return UIGraphicsGetImageFromCurrentContext()
}
UIGraphicsBeginImageContextWithOptions(targetRect.size, false, 0)
defer { UIGraphicsEndImageContext() }
let context = UIGraphicsGetCurrentContext()!
// Drawing image
clippedPath.addClip()
makeImage()?.draw(in: targetRect)
return UIGraphicsGetImageFromCurrentImageContext()
}
}
So it seems like this pitfall has something to do with UIBezierPath(roundedRect: targetRect, cornerRadius: 8).addClip()
, and I try to add mask to image in step 1, add corner to image in step 2. The code is like this
extension UIImage {
func thumbnails() -> UIImage? {
let targetRect = CGRect(x: 0, y: 0, width: 100, height: 150)
UIGraphicsBeginImageContextWithOptions(targetRect.size, false, 0)
defer {
UIGraphicsEndImageContext()
}
UIBezierPath(roundedRect: targetRect, cornerRadius: 8).addClip()
let makedImage = self.makedImage()
makedImage?.draw(in : targetRect)
return UIGraphicsGetImageFromCurrentImageContext()
}
func makedImage()->UIImage?{
let targetRect = CGRect(x: 0, y: 0, width: 100, height: 150)
let someBarRect = CGRect(x: 0, y: 100, width: 100, height: 50)
UIGraphicsBeginImageContextWithOptions(targetRect.size, false, 0)
defer {
UIGraphicsEndImageContext()
}
let context = UIGraphicsGetCurrentContext()!
draw(in : targetRect)
// Drawing a transparent mask
UIColor.black.withAlphaComponent(0.4).setFill()
context.fill(targetRect)
// Drawing bar
UIColor.white.withAlphaComponent(1).setFill()
context.fill(someBarRect)
return UIGraphicsGetImageFromCurrentImageContext()
}
}