Programmatically Getting a Screencapture of any UIView

July 27th, 2009 Posted by: (ELC) - posted under:Snippets

Introduction

Hey guys. This post is in response to a comment made in my last post about NSTimers. Techy asked if we could do a post on how to take screenshots programmatically using the iPhone SDK. For this minor project we will be creating a small web browser application that will start at www.google.com, and have a button on a toolbar at the bottom to take a picture of the web view and save it into you photo library. Lets take a look.

Screenshots

Source

You can get the source here: Screenshot Project

Steps

Step 1

Create a view based application in xCode. Call it whatever.

Step 2

In the header for your view controller declare the following:

#import
 
@interface ScreenCaptureViewController : UIViewController
{
	IBOutlet UIWebView *webview;
}
 
@property (nonatomic, retain) IBOutlet UIWebView *webview;
 
-(IBAction)captureScreen:(id)sender;
 
@end

Step 3

Open up your view controller’s XIB file.

  • Drag in a UIToolbar and put it at the bottom of the screen.
  • Drag in a UIToolbarButtom and name it appropriately.
  • Drag in a flexible space holder on either side of the button to center it.
  • Drag in a UIWebView to take up the rest of the screen above the toolbar.
  • Connect the UIWebView to our webview IBOutlet.
  • Connect out UIToolbarButton to our IBAction catureScreen:(id)sender.

Step 4

Uncomment out the viewDidLoad method and use the following code:

- (void)viewDidLoad
{
    [super viewDidLoad];
 
    [webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]]];
}

Step 5

All the is left to do is create the IBAction captureScreen. This is the code for the method, place it in the main file for your view controller.

-(IBAction)captureScreen:(id)sender
{
	UIGraphicsBeginImageContext(webview.frame.size);
	[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}

Conclusion

So that is it. You can use this general code to take a screenshot of any UIView subclass. All you need to do is replace webview.frame.size in the third line with foobar.frame.size where foobar is any UIView subclass. Hope this answered your question Techy. Happy Coding.

  • Marcelo

    Great tutorial. Excellent website. I recommend.

    Salute

  • Ryan

    FYI – this doesn’t work correctly if the view has had a transform applied. For example, if you apply a transform to a UIImageView, then attempt to use this technique to save the transformed image, you actually get the original. There are functions for applying a transform to the graphics context, but finding the right order and offsets to apply them has proven much more difficult than I thought.

  • kk

    Great Post.. I always read your post.

    Correct me if I am wrong. I guess this feature is already there in Iphone. when you press menu button and the button which is used to lock Iphone at the same time, it will capture the screenshot and saves it to Photos folder in Iphone.

  • http://www.rightsprite.com Collin

    Hey KK,

    Yeah holding the home button and power button will take a screenshot. However this takes a screenshot of the entire screen while my example shows you how to customize that effect a bit and instead take a screenshot of any specific view you like. Thanks for reading and Happy Coding!

  • http://web-geeks.com Techy

    Thanks a whole lot! This website has helped me so much..

  • Pingback: Zrzut ekranu w iPhone | appledev.pl

  • http://jainmarket.blogspot.com rahulvyas

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    this line gives warning

    no renderInContext method found..
    it still works..but why there is warning

  • BeckzZ

    I get a warning too at this line…
    and the app won’t work…Getting Errormessage “GDB: Interrupted” in Simulator…

    don’t know how to fix it…

    By the way: awesome Tutorials! Keep going!

    • http://inZania.com Zane Claes

      For those of you getting the warning, include the Quartz Core header:
      #import

      XCode needs this header to properly “understand” layers.

      However, I’m having the same problem as Ryan. I’m baking my UIView into an image using the renderInContext, but despite the fact that I have applied transformations to the UIView I’m still getting the original as output. I’ve even tried applying the transformations to the layer itself instead of to the view. If anyone has a solution please let me know – otherwise I’ll try to find the magic order that will apply the proper transformations to the image.

  • MeHim

    the code works fine but i have tried to capture textview but with no success !
    any help !

  • Tina

    Hi, Zane and Leo. Have you guys ever found solutions to this problem (the method isn’t working correctly when views are transfromed)? I’m working on the same thing, but couldn’t get it behave like the way I expected. Applying the transformations to the images will be my last choice…
    If anyone knows the answer please tell me, I’d appreciate it.

  • Sukhwinder

    Hi all,
    I am getting warning while using renderInContext: and I think its the PRIVATE API call. So apple will definitely reject our app.
    Any other solution??
    Thanks

    • Amir

      include QuartzCore/QuartzCore.h .. to remove the warning .. i posted the same line in my last post but ain’t appearing… don know why :(

  • Amir

    Add this line in your code:

    #include

    it will remove the “no renderInContext method found” warning….
    can we get a screenshot from the above code in simulator?? or I need to check it on device?

  • Henry Fok

    I am using IOS 4.2.1. I am working on a Camera application that have a snowing effect as CameraOverlay.

    A UIView is firstly added as a CameraOverlayView of Camera. Then a number of subviews of SNOW is added to the UIView.

    The problem now is whether a way to capture the photo with those SNOWs ?

    I tried to use the above provided methods and draw the UIView to Context and get back the jpg. But the Snows are not there.

    Any hint ?

    • Trent

      Henry, i am running into the same problem, please let me know if you have figured this out.

  • Nak

    i try it! It work but the result is not like your result! My saved image in Photos is not the whole screen! :( It seem like crop from the center of the image. Can you please tell me how to fix this?

    • Nak

      thank you! it works now!

    • Sergio Andrés Ibañez Kautsch

      If you want to take an screenshot of the whole window programmatically, you have to get the UIWindow from your app delegate., you have to get the UIWindow from your app delegate.

      • Tkw1976

        How do you get the UIWindow from the app delegate?

        • Tkw1976

          getting error message for    [self.view.layer

          • Rajneesh071

            UIGraphicsBeginImageContext(self.view.window.frame.size);

  • Xixi

    Custom made jewelery will help you create the personalized style assertion that will arranged you apart using the common style trends. It requires http://www.meizitangbotanicalslimming.us.com/meizitang-botanical-slimming/18-packs-new-meizitang-botanical-slimming-natural-soft-gel.html courage and expertise to stand out using the crowd.

  • Rcutshaw

    How can one capture a dynamically changing screen UI in a video?  The screen UI I have also has a video preview background, which I like to capture along with the UI.  Thanks.

  • Hbastan27

    These would result in blurred image on retina supported device , hence use : UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); instead of UIGraphicsBeginImageContext(webview.frame.size);

  • Mattgreen1977

    How might you take a screenshot of a UIImageView which has had transforms applied (i.e. a rotation). Currently it returns a screenshot of the UIImageView unrotated?

  • Jacqueline Smith

    This is AMAZING good!  I used this to save a UIIMageView.  Thank you so much for the time you give to put this up.  Cheers

canakkale canakkale canakkale balik tutma search canakkale vergi mevzuati bagimsiz denetim vergi mevzuati ozurlu engelliler