Reputation: 3401
I want to render a UIView to an image. My go-to UIView category for this is
- (UIImage *)num_renderToImage
{
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
However in this case, the UIView has elements that draw outside its bounds and the above clips them. Altering the size passed to UIGraphicsBeginImageContext
doesn't help since the size grows down and to the right, but these elements are above and to the left. What's the right way to do this?
Upvotes: 3
Views: 1400
Reputation: 1197
I made this more general version in Swift 5.0 if anyone has the problem. Just set the offset to the value you want :
private func snapshotView(cell:UIView) -> UIImageView
{
// by how much extra point out of the view bounds you want to draw your snapshot
let offset:CGFloat = 10
let frame = cell.bounds.union(CGRect(x:-offset * 2.0,y:-offset * 2.0,
width:cell.bounds.width,
height: cell.bounds.height)).size
UIGraphicsBeginImageContextWithOptions(frame, false ,0)
let context = UIGraphicsGetCurrentContext()
context!.translateBy(x: offset, y: offset);
cell.layer.render(in: context!)
let snapshotImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return UIImageView(image: snapshotImage)
}
Upvotes: 0
Reputation: 86
In the scenario above, with a UIView
clipping a UIButton
that draws outside its bounds, you might try:
- (IBAction)snapshot:(id)sender {
UIButton *button = sender;
UIView *v = button.superview;
// Prepare the rectangle to be drawn
CGRect allTheViews = CGRectUnion(v.bounds, button.frame);
UIGraphicsBeginImageContext(allTheViews.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// This is what you differently
CGContextTranslateCTM(context, -allTheViews.origin.x, -allTheViews.origin.y);
// This part is the same as before
[v.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[UIImagePNGRepresentation(img) writeToFile:@"/tmp/foo.png" atomically:NO];
}
Here we're taking the union of what we want to draw, then translating the CTM so it's in view in the graphics context we're drawing into.
(This example, in particular, is hooked up to the action of the button and writes the UIImage
of the button and containing view out to a file. You can adjust as your needs require.)
Upvotes: 5