I'm trying to cut an transparent square in a UIImage, however I honestly have no idea where/how to start.
Any help would be greatly appreciated.
Thanks!
I'm trying to cut an transparent square in a UIImage, however I honestly have no idea where/how to start.
Any help would be greatly appreciated.
Thanks!
Presume that your image is being displayed in a view - probably a UIImageView. Then we can punch a rectangular hole in that view by masking the view's layer. Every view has a layer. We will apply to this view's layer a mask which is itself a layer containing an image, which we will generate in code. The image will be black except for a clear rectangle somewhere in the middle. That clear rectangle will cause the hole in the image view.
So, let self.iv
be this UIImageView. Try running this code:
CGRect r = self.iv.bounds;
CGRect r2 = CGRectMake(20,20,40,40); // adjust this as desired!
UIGraphicsBeginImageContextWithOptions(r.size, NO, 0);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddRect(c, r2);
CGContextAddRect(c, r);
CGContextEOClip(c);
CGContextSetFillColorWithColor(c, [UIColor blackColor].CGColor);
CGContextFillRect(c, r);
UIImage* maskim = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CALayer* mask = [CALayer layer];
mask.frame = r;
mask.contents = (id)maskim.CGImage;
self.iv.layer.mask = mask;
For example, in this image, the white square is not a superimposed square, it is a hole, showing the white of the window background behind it:
EDIT: I feel obligated, since I mentioned it in a comment, to show how to do the same thing with a CAShapeLayer. The result is exactly the same:
CGRect r = self.iv.bounds;
CGRect r2 = CGRectMake(20,20,40,40); // adjust this as desired!
CAShapeLayer* lay = [CAShapeLayer layer];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, nil, r2);
CGPathAddRect(path, nil, r);
lay.path = path;
CGPathRelease(path);
lay.fillRule = kCAFillRuleEvenOdd;
self.iv.layer.mask = lay;
Here's a simple Swift function cut#hole#inView
to copy and paste for 2017
func cut(hole: CGRect, inView view: UIView) {
let path: CGMutablePath = CGMutablePath()
path.addRect(view.bounds)
path.addRect(hole)
let shapeLayer = CAShapeLayer()
shapeLayer.path = path
shapeLayer.fillRule = .evenOdd
view.layer.mask = shapeLayer
}
Just needed the Version from @Fattie, thanks again! Here is the updated Code for Swift 5.1:
private func cut(holeRect: CGRect, inView view: UIView) {
let combinedPath = CGMutablePath()
combinedPath.addRect(view.bounds)
combinedPath.addRect(holeRect)
let maskShape = CAShapeLayer()
maskShape.path = combinedPath
maskShape.fillRule = .evenOdd
view.layer.mask = maskShape
}
If you want the cutout to have rounded corners you can replace combinedPath.addRect(holeRect)
with rectanglePath.addRoundedRect(in: holeRect, cornerWidth: 8, cornerHeight: 8)
.
Here's the updated code to cut a hole in an UIImage (instead of UIView) using Swift:
func cut(hole: CGRect, inView image: UIImage) -> UIImage? {
UIGraphicsBeginImageContext(image.size)
image.draw(at: CGPoint.zero)
let context = UIGraphicsGetCurrentContext()!
let bez = UIBezierPath(rect: hole)
context.addPath(bez.cgPath)
context.clip()
context.clear(CGRect(x:0,y:0,width: image.size.width,height: image.size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
context.clear(someRect)
That's the whole thing. .clear
(For example, here's a red image with a square hole.)
let frame = CGRect(origin: .zero, size: sz)
let fmt = UIGraphicsImageRendererFormat()
fmt.scale = 1
let image = UIGraphicsImageRenderer(size: sz, format: fmt).image { rc in
.red.setFill()
rc.fill(frame)
rc.cgContext.clear(CGRect(x: 10, y: 10, width: 10, height: 10))
let att = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10.0)]
"test".draw(in: frame, withAttributes: att)
}
try! image.pngData()!.write(to: "red.png")
© 2022 - 2024 — McMap. All rights reserved.