[IMPORTANT: The information below is no longer up to date. Apple does now no longer allow you to use UIGetScreenImage(). Instead you need to use a different method. You can read about that on the official developer forum, located at developer.apple.com]

Not too long ago Apple decided to make on of their private APIs public. They now officially allow developers to make use of a very handy method:

+ (UIImage *)imageWithScreenContents;

Before they released it, grabbing screen contents could be a real nightmare. In some (rare) situations, it was pretty much impossible.
When you were using lots of openGL stuff in your project and wanted to grab the current state of your screen, you had to use glReadPixels();
This worked fine most of the time, but when you were dealing with transparency, it could make you pull your hair off :)

Anyways, those times are finally over.

To make use of this API, simply add the following lines to the .m file where you want to call it later:

//right below #import lines
CGImageRef UIGetScreenImage();
@interface UIImage (ScreenImage)
+ (UIImage *)imageWithScreenContents;
@end

@implementation UIImage (ScreenImage)
+ (UIImage *)imageWithScreenContents
{
    CGImageRef cgScreen = UIGetScreenImage();
    if (cgScreen) {
        UIImage *result = [UIImage imageWithCGImage:cgScreen];
        CGImageRelease(cgScreen);
        return result;
    }
    return nil;
}
@end

Now you can easily do something like this:

- (void)saveScreenshotToPhotolibrary {
	UIImageWriteToSavedPhotosAlbum([UIImage imageWithScreenContents], nil, nil, nil);
}

Congrats! You just saved an image with screen contents to your iPhone photo library.

5 Responses to “Screen capturing on iPhone”

  • Teo:

    Hi, i tried your code but didn’t work for me
    I’m using emulator for iphone 4.0 and calling him with: UIImage *image = [UIImage imageWithScreenContents];
    I put it before the implemantation of my viewController (class which has to call it)

    but image is 0×0 where i’m wrong ?

    i was using this code grabbed on a forum; it capture, but only the foreground window, so if your application goes in background it doesn’t work anymore.

    - (UIImage*)screenshot
    {
    // Create a graphics context with the target size
    // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
    // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
    CGSize imageSize = [[UIScreen mainScreen] bounds].size;
    if (NULL != UIGraphicsBeginImageContextWithOptions)
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    else
    UIGraphicsBeginImageContext(imageSize);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // Iterate over every window from back to front
    for (UIWindow *window in [[UIApplication sharedApplication] windows])
    {
    if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen])
    {
    // -renderInContext: renders in the coordinate space of the layer,
    // so we must first apply the layer’s geometry to the graphics context
    CGContextSaveGState(context);
    // Center the context around the window’s anchor point
    CGContextTranslateCTM(context, [window center].x, [window center].y);
    // Apply the window’s transform about the anchor point
    CGContextConcatCTM(context, [window transform]);
    // Offset by the portion of the bounds left of and above the anchor point

    CALayer *layer = (NSObject*)[window layer] ;

    CGContextTranslateCTM(context,
    -[window bounds].size.width * layer.anchorPoint.x,
    (-[window bounds].size.height * layer.anchorPoint.y) -21);

    // Render the layer hierarchy to the current context
    [[window layer] renderInContext:context];

    // Restore the context
    CGContextRestoreGState(context);
    }
    }

    // Retrieve the screenshot image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;
    }

  • friendlydeveloper:

    Hi there,

    I remember using a similar piece of code in the past and it worked without problems.
    I’ll check on this and report back.

    Cheers

  • friendlydeveloper:

    Hi there,

    can you please explain what you mean by “i was using this code grabbed on a forum; it capture, but only the foreground window, so if your application goes in background it doesn’t work anymore.” ?

    Are you trying to capture the screen when the app enters the background mode (e.g. user decides to use a different app and later returns to yours)?

    Thanks.

  • Saktheeswaran:

    Hi,

    I want to record the iPhone screen as a video in my program not from camera..
    for that i need sample code..

    Thanks in advance.

  • friendlydeveloper:

    Hi there,

    I don’t think there is an easy solution to what you’re up to. I never had to implement something like that into any of my apps. Therefore I’m afraid, I can not provide any sample code.
    However, I’d start off by looking into “iPhone video creation” (google it). Maybe also read up on ffmpeg features (there is a free iPhone version of ffmpeg out there).
    Writing your own libraries is most likely overkill.

    I can offer you to do some investigation and write a working sample for you. However, since I’m a full time developer, I can not offer such a service for free. Just let me know, in case you are interested in details.

    Good luck!

Leave a Reply

An App, you might like:
We recommend…
You might also like…
Get Adobe Flash playerPlugin by wpburn.com wordpress themes