Background transparency is lost when creating a UIImage from a UIView hierarchy

| | August 8, 2015

I’m working on an app that will let the user put an image in a frame. They can then share that image in some way, using the iOS share sheet. The problem I’m having is that the frame has rounded corners, but when I test by saving the image to the camera roll, the background is white, not transparent, and I can’t figure out how to make it save with a transparent background.

Here is my code:

UIGraphicsBeginImageContextWithOptions(self.framedImage.bounds.size, NO, 0.0f);
[self.framedImage drawViewHierarchyInRect:self.framedImage.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

//present the system share sheet for the image
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[image] applicationActivities:nil];

Here is my view hierarchy, from Xcode’s view debugger:

view hierarchy

The highlighted UIView is self.framedImage in the code above. The UIImageView and the UIButton containing the UIImageView are all part of the hierarchy that is saved.

I understand that to use UIGraphicsBeginImageContextWithOptions with the opaque flag set to NO means that my image must have an alpha channel, but as far as I can see, it does. The UIView, UIImageView and UIButton all have [UIColor clearColor] as their background colours, and for all three, the ‘Opaque’ checkbox in Interface Builder is unchecked. When I inspect the views in the debugger, they all have an alpha value of 0 for the background colour.

I have experimented with explicitly setting the background to [UIColor clearColor] in the code, immediately before the snippet above, but it still saves with a white background. I have tried changing the background to another colour (purple) and that saved as I’d expect with a purple background. So the problem seems to be that the transparent area of the UIView is being converted to an opaque white colour in the UIImage.

Does anyone know what I’m missing here?

One Response to “Background transparency is lost when creating a UIImage from a UIView hierarchy”

  1. Thanks to dasblinkenlight’s comment I was able to find the problem.

    I was passing the UIImage to a UIActivityViewController, in order to present the system share sheet. But when I pressed the “Save Image” button to save the image to the camera roll, by default it saved as a jpeg, which doesn’t support transparency. Converting the image to a PNG before passing it to the UIActivityViewController solved the problem.

    Here’s the fixed code:

    UIGraphicsBeginImageContextWithOptions(self.framedImage.bounds.size, NO, 0.0f);
    [self.framedImage drawViewHierarchyInRect:self.framedImage.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    //convert to PNG
    NSData *pngImageData = UIImagePNGRepresentation(image);
    
    //present the system share sheet for the PNG data
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[pngImageData] applicationActivities:nil];
    

Leave a Reply