Making screenshots

April 28th, 2009 by Chris Leave a reply »

iPhone / iPod touch allows you to make screenshots (saves the contents as an image) by pressing both home and power button, although many users don’t know this functionality. If you go to your camera roll or sync photos with your computer, every screenshot you make is an image 320 x 480 px.

Today I will show you how to make a screenshot of arbitrary size using Quartz. What does arbitrary size mean? Well you can not only save the smaller part of your screen, but, if you for example have bigger view than 320×480 px you can save it all, not only the visible part.

Before you start, you have to add the QuartzCore framework to the project. All frameworks can be find here:

/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ iPhoneOSxxx.sdk/System/Library/Frameworks

The part in bold can be different for each of you, in my case it’s iPhoneOS2.2.sdk. But there is much easier way to get to the Frameworks folder.

revealframeworkfinder

As you see above in Xcode, ctrl-press (or using your right mouse button) any of existing frameworks and choose Reveal in Finder.

finderframeworks

Now in Finder drag QuartzCore.framework to the Frameworks group into your project. It’s up to you if you decide to copy the item or simply link it. The framework has been added, now in the class which fill be making screenshots, you need to add a line to import the part of that framework:

#import <QuartzCore/QuartzCore.h>

You can add this line in either header (.h) or implementation file (.m).

Now it’s time to add the method which will make a screenshot and explain how it works:

-(void)saveToCameraRoll {
	UIGraphicsBeginImageContext(self.view.bounds.size);
	[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	UIImageWriteToSavedPhotosAlbum(viewImage, self, nil, nil); 

	/* 
	flashView.alpha = 1;
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDuration:0.5];
	flashView.alpha = 0;
	[UIView commitAnimations];
	UIAlertView *alert= [[UIAlertView alloc] initWithTitle:nil message:@"Photo saved to your camera roll" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
	[alert show];
	[alert release];
	*/
}

I’ve implemented the saveToCameraRoll method were first five lines do everything you need. It’s quite difficult to discuss it, as long as I never mentioned about Quartz drawing, contexts, layers… But, first line creates the context of our view (UIViewController’s self.view) size. Using that context’s frame (it’s not frame properly speaking) it contents is rendered (2nd line) and saved to an viewImage. 4th line is closing the context as we do not need it anymore, and the 5th line puts viewImage to the Camera Roll.

How about the part in the comment ( /* and */ )? Well it’s my idea how to copy the animation iPhone uses while making the screenshot using home and power buttons. I created the flashView - simple white view of the same size of my self.view most time 100% transparent. When the user decides to create a screenshot using a button I provided in the application, flashView become visible and during half a second it’s transparent again. And the alert to inform what has just happen.

Please remember that above method saves the whole self.view and all it’s subviews. So whatever is a subview of self.view will be saved as well. You can change the alpha property of anything you don’t want to save and reveal what’s behind it, and after screenshot was made bring alpha to normal. While making a screenshot as long as it will be one procedure – one task user won’t see any changes in interface. Example:

-(void)saveToCameraRoll {	topView.alpha = 0;

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

	topView.alpha = 1;

}

As always (don’t thank me) I provided an sample project. It alows you to make screenshot of whole iPhone screen (320 x 480 px), only central part (320 x 240 px) and again the whole iPhone screen without button on the bottom.

screenshotssimulator

xcodeproj

Download the project

Ohh, I would forget. One thing more. Making screenshots on simulator is very quick, unfortunately, it takes few more seconds to render everything on real device.

Advertisement

3 comments

  1. Rich says:

    Works great.
    But how do you adjust the size of the screenshot?
    I want to crop the screenshot to a smaller size.

    • Chris says:

      You can make a transform (scale) to 50% for example right before you start the image context and transform it back – either to 100% or transform identity after you finished with screenshot.

      Regards
      Chris

  2. Edgard Rodriguez says:

    For Me work Like a Charm.

    thanks bro

Leave a Reply