5 Ways to Take Screenshots of Your iPhone App

Jul 30, 2009   //   by Derek van Vliet   //   Development  //  16 Comments

Screenshots are an integral tool in application development, not to mention marketing. You may find you need a screenshot in any number of situations. Here are 5 ways you can capture a screenshot of your iPhone app. Each one is useful in a different way.

Do It With OS X

The first method is good old screen capture that is built into OS X. This is, of course, not exclusive to iPhone apps. You can hold down Command-Shift-3 to save a screenshot to your desktop in PNG format. This is useful for if you want to take a screenshot while you are running your app in the emulator.

Even more useful, in my opinion, is the Command-Shift-4 function. This turns your cursor into cross-hairs and lets you select a region of the screen to save as your screenshot, again as a PNG. This is great if you just wanted to grab a portion of your app.

You can also add Ctrl to both of the above keyboard shortcuts to save the screenshot to your clipboard instead of to disk. Then you can go paste the screenshot into Photoshop or some other image editor.

Do It With Grab

Grab is an application that comes with OS X which you can find in your Applications/Utilities folder. It features the unique ability to take a screenshot of a window:

grab-menu

This means if you run your app in the iPhone Simulator and then use Grab, you can take screenshots of your app looking all hot in the actual device with just a couple of clicks. This is a great way to get shots of your app in the iPhone if you don’t own one or aren’t a paid developer. Here’s the result:

grab

Screenshots that come out of Grab are in TIFF format.

Do It With Xcode

Xcode’s Organizer tool provides a simple interface for taking screenshots of whatever is currently displaying on an iPhone that is connected to your computer. Open it by going to Xcode’s Window menu and selecting Organizer or just hit Ctrl-Command-O.

organizer

Once it is opened, select your iPhone from the Devices section on the left. Then go to the Screenshot tab in the main section. Now use your application on the iPhone until it is in a state where you want to take a screenshot. Finally, press the capture button in Organizer and boom: you’re done.

Xcode saves screenshots as PNG files in the following folder on your machine:

~/Library/Application Support/Developer/Shared/Xcode/Screenshots/

Do It With the iPhone

Did you know you can take a screenshot of anything that the iPhone is doing at any time? It’s true. Just press and hold the home button. While you’re holding it, press and release the Sleep/Wake button. The iPhone’s screen will flash and the camera shutter sound will play. The screenshot will have been saved to your camera roll, which you can access in the Camera app or the Photos app.

iphone

Do It With Code

Finally, you can capture screenshots at precise moments in your application by using the following pair of objective-c methods. The first one, captureView, returns a UIImage that contains a render of any UIView (except EAGLView, see below). If you pass your app’s UIWindow into this method, it will return you a screenshot of the app.

The second method, saveScreenshotToPhotosAlbum, takes it a step further and saves an image that contains a render of any UIView to your iPhone’s photo album.

#import 
 
- (UIImage*)captureView:(UIView *)view {
	CGRect rect = [[UIScreen mainScreen] bounds];
	UIGraphicsBeginImageContext(rect.size);
	CGContextRef context = UIGraphicsGetCurrentContext();
	[view.layer renderInContext:context];
	UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	return img;
}
 
- (void)saveScreenshotToPhotosAlbum:(UIView *)view {
	UIImageWriteToSavedPhotosAlbum([self captureView:view], nil, nil, nil);
}

Since the above 2 methods don’t work for EAGLView, we need another solution. Below are a pair of methods that do the equivalent of the above 2 for apps using EAGLView, courtesy iPhone Dev SDK Forum.

- (UIImage*) getGLScreenshot {
    NSInteger myDataLength = 320 * 480 * 4;
 
    // allocate array and read pixels into it.
    GLubyte *buffer = (GLubyte *) malloc(myDataLength);
    glReadPixels(0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 
    // gl renders "upside down" so swap top to bottom into new array.
    // there's gotta be a better way, but this works.
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
    for(int y = 0; y <480; y++)
    {
        for(int x = 0; x <320 * 4; x++)
        {
            buffer2[(479 - y) * 320 * 4 + x] = buffer[y * 4 * 320 + x];
        }
    }
 
    // make data provider with data.
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
 
    // prep the ingredients
    int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = 4 * 320;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
 
    // make the cgimage
    CGImageRef imageRef = CGImageCreate(320, 480, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
 
    // then make the uiimage from that
    UIImage *myImage = [UIImage imageWithCGImage:imageRef];
    return myImage;
}
 
- (void)saveGLScreenshotToPhotosAlbum {
	UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil);
}

16 Comments

  • Nice article, you can also add this tool to the list, which specifically captures the simulator:
    http://www.curioustimes.de/iphonesimulatorcropp…

  • Thanks, your captureView: is just what I needed. Well, almost. I need to capture not
    the whole screen, but a rectangular portion of it, so I wrote this:

    - (UIImage*)captureView:(UIView *)view bounds:(CGRect)rect
    {
    UIGraphicsBeginImageContext(CGSizeMake(320, 480));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClipToRect(context, rect);
    [view.layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
    }

    which works just fine.

  • Thanks, your captureView: is just what I needed. Well, almost. I need to capture not
    the whole screen, but a rectangular portion of it, so I wrote this:

    - (UIImage*)captureView:(UIView *)view bounds:(CGRect)rect
    {
    UIGraphicsBeginImageContext(CGSizeMake(320, 480));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClipToRect(context, rect);
    [view.layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
    }

    which works just fine.

  • Great article, works realy well. What I can't work out is how to access the iPhone screen from my app so I can make a png in it so it appears that the app is transparent? Any ideas?

  • Hi moldie, I'm having trouble understanding what you are attempting to do. If I read correctly, you're trying to take a screen capture of your app at run time? If so you can accomplish this with the above code. I don't understand what you mean by “so it appears that the app is transparent.” Could you please elaborate?

  • Hi, what I was trying to do was capture the screen 'before' the app launch so I could then use the png to play around with it in my app – like for fun say load the app in and “appear” to rub out the phone icons with my finger. Any of this making sense? I tried loading a transparent view then using the code but it was blank.

  • Ah now I understand.

    From tests that I have run, it looks like the earliest opportunity to run code happens after the iPhone has cleared away the homescreen and launched your app's splash screen. I'm not sure it's possible to take a screenshot of the icons on the homescreen before your app runs, but if there's a chance, you'll want to see if you can take a screenshot in the entry point function of the app (eg. main).

  • I'm trying to capture a small portion of a MKMapView. I have an annotation view that lies overtop.

    If I pass in the annotation view, all I get is what I draw myself in the annotation view, and nothing from the MKMapView background. Even if I draw nothing and the annotation view is 100% transparent and empty, nothing shows up from the MKMapView.

    If I pass in the MKMapView, I capture the whole map.

    If I pass in the MKMapView but use CGContextClipToRect with the small view's frame or bounds, I get a big image the size of MKMapView, empty but for the clipping rectangle.

    If I use UIGraphicsBeginImageContext to make a smaller context matching the small view's size, I only capture the top-left portion of the MKMapView, not the part I want. And calling CGContextClipToRect with the small view's frame just produces an empty image.

    Will I have to capture the full map, convert to a bitmap, and extract from that? Is there some other way to do this?

  • You can capture screen caps from the iPhone simulator using control-command-C …I usually use Preview “New from clipboard” and save the result as a PNG.

  • You can capture screen caps from the iPhone simulator using control-command-C …I usually use Preview “New from clipboard” and save the result as a PNG.

  • how can i put it under a button? I did it
    [but addTarget:self action:@selector(captureView:view:)
    forControlEvents:UIControlEventTouchUpInside]; but it throws an exception ” unrecognized selector sent to instance XXXXXXXX”

  • The Power button on my iPhone is broken, can you change the settings to change which button takes the screen shot?

  • Hi Moldie!

    I know this is an uber-old posting from you. Would like to know if you had any success with what you were trying around the “pre-screenshot”?

    Thanks for any insight…..this was a good article although a little vintage at this point

  • My power button on my iphone doesnt work, im not sure how to screenshot things without using the power button, i read this artical and it said to use the iPhone simulator, and a command thing? What is that?

  • you can go to settings and enable AssistiveTouch, then you`ve all the functionality of the normal buttons.

  • Maybe Apple updated the iOS Simulator since this was written…

    In the Simulator, hit Cmd-S. That saves a date-stamped screen shot to your desktop. It’s under the File menu.

Leave a comment

Our Games

Latest Tweets