Vince
Vince

Reputation: 73

Non-null invalid context error when creating a UIImage from a UIView

I'm using the following to generate a UIImage from a UIView

UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

which usually works but about half the time, I get this error when renderInContext is called:

<Error>: CGContextDrawImage: invalid context 0x84d0b20

Does anyone have any idea why this happens or how to even detect when it happens? I think I would feel better if the address for the context was 0x0 because it would at least be something I could test for and deal with but this so far this has me stumped.

Edit: Whoops. Meant to use view.frame.size and not view.bounds.size.

Upvotes: 3

Views: 2015

Answers (3)

Mikey
Mikey

Reputation: 1332

I had a similar issue but was able to solve it by pushing and popping the image context prior to my layer rendering its contents.

Try something like this:

UIImage *snapshotImage = nil;
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, view.layer.contentsScale);
{
    CGContextRef imageContext = UIGraphicsGetCurrentContext();

    if (imageContext != NULL) {
        UIGraphicsPushContext(imageContext);
        {
            [view.layer renderInContext:imageContext];
        }
        UIGraphicsPopContext();
    }

    snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();

For what it's worth, there are alternative (and more efficient) ways to obtain a snapshot but it's still under NDA.

Upvotes: 5

Cowirrie
Cowirrie

Reputation: 7226

If you create a context with width or height zero, the context will be invalid. This could happen if the view size is zero on either axis, or if the view is nil.

Also, since you're rendering a layer, you might want to get the layer bounds and scale, instead of the view bounds and screen scale. Most of the time these values will be the same, but it's good to allow for the times they are not.

// Debugging output to see how if an invalid context is being created due to zero size.
NSLog(@"View = %@", view);
NSLog(@"View size = %@", NSStringFromCGSize(view.bounds.size));

UIGraphicsBeginImageContextWithOptions(view.layer.bounds.size, YES, view.layer.contentsScale);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Upvotes: 6

Nitin
Nitin

Reputation: 7461

UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Hope, this will help you....

Upvotes: 0

Related Questions