user416445
user416445

Reputation:

Save UIView to a transparent PNG

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

Answers (4)

Azhar
Azhar

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

Lukas Kalinski
Lukas Kalinski

Reputation: 2243

In my case, I forgot the opaque property. It should be set to NO:

view.opaque = NO;

Upvotes: 10

Arndt Bieberstein
Arndt Bieberstein

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

Gilad Novik
Gilad Novik

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

Related Questions