14

Before iOS7 I use UIGetScreenImage() function to take the screenshot easily, but in iOS7, it becomes deprecated, now are there any good methods to archive this?Thank you!

Addition: I need take screenshot for the entire screen at any view

Suge
  • 2,808
  • 3
  • 48
  • 79
  • 1
    I think this might help: http://stackoverflow.com/questions/18956611/programmatically-screenshot-works-bad-on-ios-7 – P. Sami Feb 07 '14 at 13:55
  • @P.Sami, @SamkitJain,thank you for your answer, but it cannot solve the problem for me,my app is a jailbreak tweak app running inside `SpringBoard`, I want to capture the screenshot at any view of any app at top, include the home screen, not only the views of my app.What can I do? – Suge Feb 08 '14 at 10:37
  • @Suge you look at the duplicate question and read its answers. Jailbreaking is not black magic (well, ...), tweaks have access to the same APIs that official apps use. –  Feb 11 '14 at 00:40
  • @H2CO3, my tweak runs inside `SpringBoard`, do you mean I can use `snapshotViewAfterScreenUpdates` method to take screenshot for the entire screen whenever which app is at front most? But how can I get the view at front most? – Suge Feb 11 '14 at 00:52
  • @Suge You snapshot `[UIWindow mainWindow]` itself. –  Feb 11 '14 at 05:52
  • @H2CO3, use `[UIWindow mainWindow]` I can get only the view of `SpringBoard`, not the front most app. – Suge Feb 12 '14 at 05:01
  • You can use the following ways: [enter link description here][1] [enter link description here][2] [1]: http://stackoverflow.com/questions/3610604/how-to-take-a-screenshot-of-the-iphone-programmatically [2]: http://stackoverflow.com/questions/18679787/objective-c-capture-screenshot-of-all-views-within-custom-frame – Alexander Merchi Feb 12 '14 at 20:30

4 Answers4

4

I came across the same problem, but have no ideas how to solve it.

I tried IOSurface - IOS Private API - Capture screenshot in background , which works well in some apps but returns a black screen in games.

Then I tried this app https://github.com/k06a/UIView-FastScreenshot/blob/master/UIView%2BFastScreenshot.m , which works well using private apis, but I can't compile it using theos, always telling me "Undefined symbols for architecture armv7: CARenderServerRenderDisplay". Edit: I figured out how to compile it using theos, but returns am empty image.

Also, https://github.com/coolstar/RecordMyScreen works well in iOS7, but it's not open source now, so I can't find out how it capture the whole screen.

Edit: RecordMyScreen's code works on iOS7 as a springboard tweak, you can refer to this file https://github.com/coolstar/RecordMyScreen/blob/master/RecordMyScreen/CSScreenRecorder.m this method "- (void)_captureShot:(CMTime)frameTime;"

Community
  • 1
  • 1
cloudycliff
  • 299
  • 1
  • 8
  • Thank you for your answer, is `RecordMyScreen` open source now?The code looks old. – Suge Feb 12 '14 at 02:31
  • RecordMyScreen isn't open source now, but after some reverse engineering with the latest version, the code for capturing screenshot seems not changed much. Also, you can refer to this fork https://github.com/Norod/RecordMyScreen which works on iOS7. – cloudycliff Feb 12 '14 at 05:25
  • I uploaded my tweak https://github.com/cloudycliff/CaptureMyScreen, when activated it will save the screenshot to /var/mobile/Documents/test.png – cloudycliff Feb 13 '14 at 04:28
  • @tesmojones the code is activated by Activator, you can set it in Settings. Or you can just add the capture code in your tweak. – cloudycliff Apr 10 '14 at 09:03
  • On the Norod version, it kept crashing with "Received memory warning." after it came back from background so I can stop the recording. There were no other apps running at the moment. Any ideas? – EmilyJ Jun 09 '14 at 15:04
1

Alternative way to replace UIGetScreenImage()

CGImageRef screen = UIGetScreenImage();

The above code is one line of code to capture the screen, but Apple does not open the above API UIGetScreenImage() for the public app. i.e. fail to upload to Apple for approval. So the alternative way to capture screen and save it are listed as below.

- (void)captureAndSaveImage
{    

    // Capture screen here... and cut the appropriate size for saving and uploading
    UIGraphicsBeginImageContext(self.view.bounds.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // crop the area you want 
    CGRect rect;
    rect = CGRectMake(0, 10, 300, 300);    // whatever you want
    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
    UIImage *img = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef);
    UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    imageView.image = img; // show cropped image on the ImageView     
}

// this is option to alert the image saving status
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    UIAlertView *alert;

    // Unable to save the image  
    if (error)
        alert = [[UIAlertView alloc] initWithTitle:@"Error" 
                                           message:@"Unable to save image to Photo Album." 
                                          delegate:self cancelButtonTitle:@"Dismiss" 
                                 otherButtonTitles:nil];
    else // All is well
        alert = [[UIAlertView alloc] initWithTitle:@"Success" 
                                           message:@"Image saved to Photo Album." 
                                          delegate:self cancelButtonTitle:@"Ok" 
                                 otherButtonTitles:nil];
    [alert show];
    [alert release];
}

some of link help you how-to-legally-replace-uigetscreenimage

codercat
  • 22,873
  • 9
  • 61
  • 85
1
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

This code can help you in getting a screenshot of the self.view which is whole of the screen of the iPhone no matter which app is in front.If you have used any layers in your view then the layers will not be included in the screenshot and for that you have to use self.view.layer.

Yieshu
  • 111
  • 1
  • 5
0

The UIView class has an method called: resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets .

But i have never worked with this method so i cannot tell you more about it.

And this post: Capture UIView as UIImage shows how you get the returned UIView into an image.

hope it is usefull.

Community
  • 1
  • 1
Mirko Brunner
  • 2,204
  • 2
  • 21
  • 22
  • Or better use the answer from Samkit Jain ;) – Mirko Brunner Feb 07 '14 at 13:59
  • 1
    thank you for your answer, but it cannot solve the problem for me,my app is a jailbreak tweak app running inside `SpringBoard`, I want to capture the screenshot at any view of any app at top, include the home screen, not only the views of my app.What can I do? – Suge Feb 08 '14 at 10:37