9

I have a UIView that uses both UIKit control and OpenGL. I'd like to get a screenshot of that view programatically.

If I use UIGraphicsGetImageFromCurrentImageContext(), the OpenGL content is blank; If I use the glReadPixels(...) method, the UIKit content is blank;

I'm confused as how to take a complete screenshot. Thank you!

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
coodi8
  • 91
  • 1
  • 1
  • 2

8 Answers8

8

use following code to take screen shot

    -(UIImage *) screenshot
     {

          CGRect rect;
          rect=CGRectMake(0, 0, 320, 480);
          UIGraphicsBeginImageContext(rect.size);

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

          UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();

          return image;
     }
Himanshu Mahajan
  • 4,779
  • 2
  • 36
  • 29
  • 1
    This code is just for take UIKit stuff...The question is more complex and well explained: he need to take also OpenGL stuff. – Matteo Gobbi May 19 '14 at 15:04
5

Well, there are few ways of capturing the iPhone screen programmatically

  1. Using UIKIT http://developer.apple.com/library/ios/#qa/qa1703/_index.html

  2. Using AVFoundation framework http://developer.apple.com/library/ios/#qa/qa1702/_index.html

  3. Using OpenGL ES http://developer.apple.com/library/ios/#qa/qa1704/_index.html

  4. Starting from iOS 7 you can also use Why does my programmatically created screenshot look so bad on iOS 7?

  5. Using UIWindow

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    UIGraphicsBeginImageContext(screenRect.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [[UIColor blackColor] set];
    CGContextFillRect(ctx, screenRect);
    [self.window.layer renderInContext:ctx];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
  6. Using UIView

    UIGraphicsBeginImageContext(self.view.frame.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

Out of these 6 options, I found the first option very convenient for copy-pasting and for applying level of compression as 1st method gives the image with true pixel data. I also like option 4, as the API comes with SDK.

Community
  • 1
  • 1
Trident
  • 810
  • 9
  • 20
  • 1
    Thanks for this, it seems that screens with sub-view controllers don't auto-add child view controller layers. But using the window seems to work for a full-screen image. Thanks! – slycrel Sep 18 '13 at 20:00
5
-(UIImage *) screenshot
{
CGImageRef UIGetScreenImage(void);
CGImageRef screen = UIGetScreenImage();
UIImage* screenImage = [UIImage imageWithCGImage:screen];
CGImageRelease(screen); // you need to call this.
return screenImage;
}
Mann
  • 5,477
  • 6
  • 45
  • 57
  • Can someone explain how it works? Also need to fix the orientation – ZYiOS Oct 07 '13 at 15:54
  • definitely not the way to go [this is why](http://stackoverflow.com/questions/3767860/uigetscreenimage-the-app-is-not-getting-the-approval-due-to-this-method) – Julian Sep 29 '15 at 12:24
2

You get result Uiimage without lose quality of image

    - (UIImage *)captureView:(UIView *)view {
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
     [view.layer renderInContext:UIGraphicsGetCurrentContext()];
     UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     return img;
     }
kb920
  • 3,039
  • 2
  • 33
  • 44
1
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = [UIImagePNGRepresentation(image) retain];
UImage *screenShot = [UIImage imageWithData:data];
Rushi
  • 4,553
  • 4
  • 33
  • 46
0

Here is how you can take a simple screenshot programmatically of a UIImage. If you want it for any other object substitute the UIImage with it.

In the .h file add NSData *Data; then in your .m file add this to your code

UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *attachimage = [[UIImage alloc]initWithData:Data];
UIImage *viImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
attachimage = viImage;
UIImageWriteToSavedPhotosAlbum(viImage, nil, nil, nil);
Mahendra
  • 8,448
  • 3
  • 33
  • 56
IronManGill
  • 7,222
  • 2
  • 31
  • 52
0

You know where the OpenGL content is located in your view. So it should be easy to copy the result of glReadPixels into the snapshot of the UIKit.

Felix K.
  • 6,201
  • 2
  • 38
  • 71
  • I'm developing a screenshot control, I don't know whether the view is implemented by UIKit or OpenGL, or mixed. If I can get the info that the view is implemented by what, the problem will be solved. – coodi8 Nov 08 '12 at 08:12
  • @coodi8 I think this could be a problem. Won't be easy because OpenGL renders directly on the graphic chip. UI-Graphics are not rendered on the graphics chip. ( AFAIK ) – Felix K. Nov 08 '12 at 08:29
0

maybe.. can you use something from here

- https://stackoverflow.com/questions/12413460/cocos2d-2-0-screenshots-on-ios-6

and here...

Why is glReadPixels() failing in this code in iOS 6.0?

Community
  • 1
  • 1
TonyMkenu
  • 7,597
  • 3
  • 27
  • 49