Wednesday, April 25, 2012

Make a snapshot from an iPhone application


Today I needed to make a snapshot programmatically. I thought it's easy:
[iPhone developer:tips];. Screen Capture using UIGetScreenImage.
Unfortunately, this approach does not work for me. People say that this API is private.
Ok. Let's make our own function.
I will add this function to my application delegate class. It looks so:
@interface myDelegate : NSObject<UIApplicationDelegate>
{
    UIWindow* window;
}

- (void) makeSnapshot;

@end
I save the snapshot in the camera roll and I have a callback notifying me about an error:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    UIAlertView *alert;
    
    // Unable to save the image  
    if (error)
        alert = [[UIAlertView alloc] initWithTitle:@"Error" 
                               message:@"Unable to save image to Photo Album." 
                              delegate:self cancelButtonTitle:@"Ok" 
                     otherButtonTitles:nil];
    else // All is well
        alert = [[UIAlertView alloc] initWithTitle:@"Success" 
                                           message:@"Image saved to Photo Album." 
                                          delegate:self cancelButtonTitle:@"Ok" 
                                 otherButtonTitles:nil];
    [alert show];
    [alert release];
}
Now from my code I can make the snapshots:
myDelegate *appDelegate = (myDelegate *)[[UIApplication sharedApplication] delegate]; 
[appDelegate makeSnapshot];
Of course these methods could be added to a UIView class in my application. So makeSnapshot will look as the following:
- (void) makeSnapshot
{
    UIGraphicsBeginImageContext([self frame].size);
    [[self layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // Save the captured image to photo album
    UIImageWriteToSavedPhotosAlbum(screenImage, self, 
                   @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
Now, I can call this makeSnapshot method, for example, from touchesBegan:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    [self makeSnapshot]; 
}
If I want to handle the touch event I needto send setUserInteractionEnabled message to the view:
[contentView setUserInteractionEnabled:YES];

Probably, this code will fail with an OpenGL ES application. I think so, because I see this thread on Cocos2d forum. Seems like people there have found a solution.

No comments:

Post a Comment