Posts Tagged ‘flash’

Making screenshots

April 28th, 2009

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.