Reputation:
I have a UIView and I want it to be stored as a transparent PNG, i.e. without the UIVIew background color...
I am currently using this code and it's working OK but with the background color :(
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* image1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(image1);
[imageData writeToFile:filePath atomically:YES];
So does anyone have any idea about getting this image as a transparent one?
Thank you in advance..
Upvotes: 16
Views: 9203
Reputation: 20680
For Objective-c you have to set opaque = NO
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
For Swift you have to set opaque = false
func imageWithView(inView: UIView) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(inView.bounds.size, false, 0.0)
if let context = UIGraphicsGetCurrentContext() {
inView.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
return nil
}
Upvotes: 0
Reputation: 2243
In my case, I forgot the opaque property. It should be set to NO:
view.opaque = NO;
Upvotes: 10
Reputation: 1128
As an addition to Gilad's answer. On retina display this may cause some quality issues. To get the retina context you may use this code from this post.
UIColor* color=self.backgroundColor;
view.backgroundColor=[UIColor clearColor];
// This is for retina render check
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
UIGraphicsBeginImageContextWithOptions(YourView.frame.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(keyWindow.bounds.size);
// And it goes up to here the rest stays the same
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* image1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(image1);
[imageData writeToFile:filePath atomically:YES];
self.backgroundColor=color;
Upvotes: 3
Reputation: 4604
Change the background color to [UIColor clear], draw the image and then set the background color back to the original color.
Since GUI updates will fire only on the next runloop cycle, the user should not see any flickering.
UIColor* color=self.backgroundColor;
view.backgroundColor=[UIColor clearColor];
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* image1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(image1);
[imageData writeToFile:filePath atomically:YES];
self.backgroundColor=color;
Upvotes: 7