snapshotViewAfterScreenUpdates on UIScreen gives blank snapshot on device - ios

I'm trying to get an image of the entire screen as the user sees it. The following code should work however it will only work in the simulator. What do I have to do to get this to work on a device running iOS 8.1?
UIView *snapshot = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:YES];
CGSize outputSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
UIGraphicsBeginImageContextWithOptions(outputSize, NO, 0);
[snapshot drawViewHierarchyInRect:CGRectMake(0.0, 0.0, outputSize.width, outputSize.height) afterScreenUpdates:YES];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Happy to try alternative strategies but the key is I want it as the user sees it - keyboards and all.
Cheers

UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)), NO, 1.0f);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)) afterScreenUpdates:NO];
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();

Related

Screen shot is coming out stretched

I have AVFoundation framework in my project and I am taking a screenshot with the previewLayer visible. When I take the screen shot the image appears to be stretched a little bit. How can I fix the stretching issue?
CGSize imageSize = [[UIScreen mainScreen] bounds].size;
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
UIGraphicsPopContext();
[self renderView:self.overlayLabel inContext:context];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
self.screenshotImage = screenshot;
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(screenshot, self, nil, nil);

Stretched UIView background gets cut off during screenshot

So, I am taking a screenshot of a subclassed UIView that I save into the device's photo stream.
Problem:
The problem is that I use resizableImageWithCapInsets to add a stretched background to my UIView, but this background gets cut off on the right side and I have no idea why. If someone could help me out it would be highly appreciated.
I add the stretched background to my UIView the following way:
[diagramBase addSubview:[self addTileBackgroundOfSize:diagramBase.frame
andType:#"ipad_diagram_border.png"]];
Which calls this method:
- (UIImageView *) addTileBackgroundOfSize:(CGRect)frame
andType:(NSString *)type
{
frame.origin.x = 0.0f;
frame.origin.y = 0.0f;
UIImageView *backgroundView = [[UIImageView alloc] initWithFrame:frame];
UIImage *image = [UIImage imageNamed:type];
UIEdgeInsets insets = UIEdgeInsetsMake(10.0f, 10.0f, 10.0f, 10.0f);
UIImage *backgroundImage = [image resizableImageWithCapInsets:insets];
backgroundView.image = backgroundImage;
return backgroundView;
}
The actual printscreen is done with this method (RINDiagramView is the name of my subclassed UIView, which I am taking a screenshot of). The rotation is in there because I need the image rotated when I save it, but I commented out that part and that is not what does the background to act weird.
- (UIImage *) createSnapshotOfView:(RINDiagram *) view
{
CGRect rect = [view bounds];
rect.size.height = rect.size.height - 81.0f;
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *capturedScreen = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *finalImage = [[UIImage alloc] initWithCGImage: capturedScreen.CGImage
scale: 1.0
orientation: UIImageOrientationLeft];
return finalImage;
}
I use Xcode 5.1 and everything is done programmatically (no storyboard and such). The base SDK is iOS 7.1.
If you're doing iOS 7+ you can use the new drawViewHierarchyInRect:afterScreenUpdates: and related methods which Apple says are really performant.
Even if you're targeting iOS 6 you should give it a try to see if you get the same problem.
Try using the correct scale?
UIImage *finalImage = [[UIImage alloc] initWithCGImage: capturedScreen.CGImage
scale: [[UIScreen mainScreen] scale]
orientation: UIImageOrientationLeft];
Use a different UIViewContentMode?
UIViewContentModeScaleToFill -> check if you can see the edges
UIViewContentModeScaleAspectFit -> check if you can see the edges, even if position is incorrect
UIViewContentModeScaleAspectFill -> check for edge right side
The reason you got a right-side cut image is caused by this line
UIImage *finalImage = [[UIImage alloc] initWithCGImage: capturedScreen.CGImage
scale: 1.0
orientation: UIImageOrientationLeft];
You made the image orientation to left, the context will thought the left-side is your top-side.And your size has a minus to the height value, so the result turns to the right-side is cut.
About the rotation, I added some code into your code.Hopes it is helpful.
- (UIImage *) createSnapshotOfView:(UIView *) view
{
CGRect rect = [view bounds];
rect.size.height = rect.size.height - 81.0f;
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
view.transform = CGAffineTransformMakeRotation(M_PI_2);
[view.layer renderInContext:context];
UIImage *capturedScreen = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *finalImage = [[UIImage alloc] initWithCGImage: capturedScreen.CGImage
scale: 1.0
orientation: UIImageOrientationLeft];
view.transform = CGAffineTransformMakeRotation(0);
return finalImage;
}
UIGraphicsBeginImageContext(self.window.bounds.size);
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:#"foo.png" atomically:YES];
for retina display, change the first line into this:
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(self.window.bounds.size);
adjust your size, may you get help..

iOS 7 taking screenshot of part of a UIView

I have a view (testView) that is 400x320 and I need to take a screenshot of part of this view (say rect = (50, 50, 200, 200)).
I am playing around with the drawViewHierarchy method in iOS 7 but I can't figure out how to do it correctly.
UIGraphicsBeginImageContextWithOptions(self.testView.bounds.size, NO, [UIScreen mainScreen].scale);
[self.testView drawViewHierarchyInRect:self.testView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Any help will be appreciated!
Thanks.
After getting the whole snapshot, you could draw it in a smaller Graphic Context in a way that you get the part you want:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), YES, [UIScreen mainScreen].scale);
[image drawInRect:CGRectMake(-50, -50, image.size.width, image.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
EDIT: Better yet, draw the hierarchy directly in that smaller context:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, [UIScreen mainScreen].scale);
[self.testView drawViewHierarchyInRect:CGRectMake(-50, -50, self.testView.bounds.size.width, self.testView.bounds.size.height) afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Try below line of code,
UIView *popSnapshot=[inputView snapshotViewAfterScreenUpdates:YES];

Setting Context for ios screenshots

I want to take a screenshot of a specific part of the screen. I have set up a method to tale a shot of the whole screen, but I want a specific section.
I know I have to change this code:
CGSize imageSize = [[UIScreen mainScreen] bounds].size;
But I tried using the CGRectMake (50,50, 400, 400) instead of [[UIScreen mainScreen] bounds].size and it gives an error... Why?
Try this :-
CGRect rect = CGRectMake(50,50, 400, 400);
UIGraphicsBeginImageContext(rect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextFillRect(ctx, rect);
[self.view.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Hope it helps you..

Screen capture for iOS [duplicate]

This question already has answers here:
iOS Screenshot part of the screen
(4 answers)
Closed 8 years ago.
i m using this codes for screen capture for iOS:
CGImageRef screen = UIGetScreenImage();
UIImage *image = [UIImage imageWithCGImage:screen];
CGImageRelease(screen);
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
CGRect screenshotFrame;
CGImageRef screenshotRef = CGImageCreateWithImageInRect(screenshotRef, screenshotFrame);
UIImage * screenshot = [[(UIImage *)screenshotRef retain] autorelease];
CGImageRelease(screenshotRef);
But my screen contain tool bar bottom of the screen.i don't want tool bar on my captured screen. How can i crop tool bar ? How can i modified my code ?
I think you can capture the layer of self.view because it the root view
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
//Retina display
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Have fun!
Try this:
UIGraphicsBeginImageContext(/*CGRECT*/);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Here in CGRect pass your rect which you want to take screenshot.
Hope it helps you..
Set your
CGRect screenshotFrame = CGRectMake(0, 0, 320, 436);
// 480(screen height) - 44(toolbar height) = 436

Resources