Taking Screenshots with the iPhone SDK
October 1st, 2008 by Michael PetrovWhy would I want to Screenshot an Application?
FMWebschool Inc. is the creator behind the FMTouch iPhone FileMaker database software. During its development I wanted to create an interesting visual effect: take a snapshot of the users workspace when they closed the database. This was done to make the opening process “smoother” since the user sees what their screen will appear like when the database completes loading. In this quick tutorial I will outline how easy it is to do with the correct tools and make your applications stunning.
As you can see on the side the FMTouch main menu contains a database entry “FMTouch Sample” with a screenshot of the Warehouses layout shown in the screen. FMTouch also animates the screenshot to pop out of the page and stick to the screen when you tap it.
So how is it done? Well it’s actually very very simple and required a bit of digging through the official documentation. Personally I was surprised that the UIView object did not have something similar to a pngRepresentation method. I decided to add this functionality in the form of an extension to UIView, this means that every object in the application (main window, a view, inputs, buttons, etc) will suddenly have the screenshot method available to them. The screenshot method that is outlined below will return a UIImage object for you to use, then as a small bonus at the end I will show the code that allows you to save a UIImage to disk.
FMWS_Screenshot_Extension.h
#import <UIKit/UIKit.h>
@interface UIView(FMWS_Screenshot_Extension)
-(UIImage*) screenshot;
@end
FMWS_Screenshot_Extension.m
//
// FMWS_Screenshot_Extension.m
//
// Created by Michael Petrov (michael@fmwebschool.com) on 06/01/08.
// Released into the public domain on the FMWebschool blog (http://fmwebschool.com/blog)
//
#import <QuartzCore/QuartzCore.h>
#import “FMWS_Screenshot_Extension.h”
@implementation UIView(FMWS_Screenshot_Extension)
-(UIImage*) screenshot {
UIGraphicsBeginImageContext(self.layer.visibleRect.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@end
Taking a Screenshot of the Whole Window
Using this in your code is very simple, include the .h file and then use this simple line:
UIImage *screenshot = [[[UIApplication sharedApplication] keyWindow] screenshot];
That takes the screenshot of the most recent UIWindow object which just happens to be a subclass of UIView with our screenshot function.
Saving the UIImage to Disk
The last thing that many of you will want to do is save the screenshot to disk, well the key here is getting a UIImage represented as a NSData object which can be saved to disk. Here is how I did it:
NSData *image = UIImagePNGRepresentation(screenshot);
[image writeToFile:@"screenshot.png" atomically:YES];
Conclusions
I hope that this quick tutorial helps you out. I think it demonstrates the power of categories which allow you to add a method such as “screenshot” to a very large group of objects, all UIView derived objects in this instance, and keep the implementation details hidden out of sight. All the code used here auto releases the objects in the internal functions, therefore it will not suck down memory beyond the immediate autorelease pool.
Please leave comments and suggestions below!


