How to take screen shot in iOS device programmatically for SOS? - ios

Using new API's like
snapshotViewAfterScreenUpdates
resizableSnapshotViewFromRect
drawViewHierarchyInRect
Using these i want to take photo in any format and need to send.

try this
UIView *screenshotView = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
UIImage *snapshotImage = [self imageFromView:screenshotView];
- (UIImage *)imageFromView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0.0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}

Related

Covert UIVIew to UIImage without presenting/displaying UIView

I am using method to convert UIView to UIImage and its doing a great job when UIView (to be converted to UIImage) is already present/displayed. But my requirement is to convert UIView to UIImage without displaying UIView. Unfortunately, this code is failing in this case and I am stuck. Any help will be appreciated.
I am using the following method:
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Your code is likely failing because you're not laying out the subviews of your view (which is done automatically when you add a view as a subview). Try something like the method I wrote below:
+ (UIImage *)imageFromView:(UIView *)view sized:(CGSize)size
{
// layout the view
view.frame = CGRectMake(0, 0, size.width, size.height);
[view setNeedsLayout];
[view layoutIfNeeded];
// render the image
UIGraphicsBeginImageContextWithOptions(size, view.opaque, 0.0f);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return renderedImage;
}
Assuming you have already got a working view, this code should work to convert the UIView to a UIImage (I'm using it to convert a gradient into an image and display the image onto a UIProgressView.
Swift:
let renderer = UIGraphicsImageRenderer(size: gradientView.bounds.size)
let image = renderer.image { ctx in
gradientView.drawHierarchy(in: gradientView.bounds, afterScreenUpdates: true)
}
Objective C:
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:gradientView.bounds.size];
UIImage *gradientImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
[gradientView drawViewHierarchyInRect:gradientView.bounds afterScreenUpdates:true];
}];
_progressView.progressImage = gradientImage;
The above code should allow you to convert any UIView to a UIImage. You should ideally be running it in the viewWillAppear (as at this point the view controller will have the correct layout sizes). If you have any problems getting this to work you can have a look at these example projects that I made for a guide on this very topic! Objective C, Swift.
Hide all subviews, and then snapshot UIview to UIImage should work, see code below
+ (UIImage *)custom_snapshotScreenInView:(UIView *)contentView
{
if (!contentView) {
return nil;
}
CGSize size = contentView.bounds.size;
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
CGRect rect = contentView.bounds;
[contentView drawViewHierarchyInRect:rect afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
return image;
}
+ (UIImage *)custom_snapshotScreenWithoutSubviews:(UIView *)contentView
{
// save hidden view's hash
NSMutableArray *hideViewsHashs = [[NSMutableArray alloc]initWithCapacity:contentView.subviews.count];
for (UIView *subview in contentView.subviews) {
if (subview.hidden == NO) {
[hideViewsHashs addObject:#(subview.hash)];
NSLog(#"Dikey:video:snap:hash = %#", #(subview.hash));
}
subview.hidden = YES;
}
// view to image
UIImage *image = [UIImage custom_snapshotScreenInView:contentView];
// restore
for (UIView *subview in contentView.subviews) {
if ([hideViewsHashs containsObject:#(subview.hash)]) {
subview.hidden = NO;
NSLog(#"Dikey:video:snap:restore:hash = %#", #(subview.hash));
}
}
// finish
return image;
}

How to capture a UIView as image which is out of currently visible frame?

Is there any way to capture a UIView to UIImage which is not currently visible or it is out of the frame. Below the code I am using now:
UIGraphicsBeginImageContextWithOptions(_myView.bounds.size, _myView.opaque, 0.0f);
[theView drawViewHierarchyInRect:_myView.bounds afterScreenUpdates:NO];
UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Try this-
-(UIImage *)imageFromView:(UIView *)myView{
UIGraphicsBeginImageContextWithOptions(myView.bounds.size, myView.opaque, [UIScreen mainScreen].scale);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

iOS screen capture is blurry for some reason

I'm trying to capture the screen inside of my app, it used to work just great, but now I only get a blurry image. like that:
This is my code:
- (UIImage *)takeScreenShotWithFrame:(CGRect)frame
{
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(frame.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(frame.size);
}
[self.view drawViewHierarchyInRect:frame afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
What am I doing wrong?
Thanks in advance!
instead of:
[self.view drawViewHierarchyInRect:frame afterScreenUpdates:NO];
Try:
CGContextRef context = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:context];

Crop taken screenshot and save image

I'm using this code to take a screenshot of my specific UIView which is inside in my main view.
UIGraphicsBeginImageContextWithOptions(_myView.frame.size, NO, [UIScreen mainScreen].scale);
[self.view drawViewHierarchyInRect:self.view.bounds afterScreenUpdates:YES];
UIImage *imageSave = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Main view size is (0,0,320,480) lets say, and myView size is (10,20,200,150)
Now i would like to capture/take a screenshot only of myView.
The above code doesn't capture exactly how i want, any suggestions?
Try this, it works for me.
- (UIImage *)snapshotOfView:(UIView *)view
{
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}

Can't get the screenshot of fullscreen in ios

This is my code..
extern CGImageRef UIGetScreenImage();
CGRect frame = CGRectMake(0, 0, 320, 548);
CGImageRef cgoriginal = UIGetScreenImage();
CGImageRef cgimg = CGImageCreateWithImageInRect(cgoriginal, frame);
UIImage *viewImage = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgoriginal);
CGImageRelease(cgimg);
It takes screen shot but not full screen. I know this problem in CGRect frame. But I don't know, how to fix that..
Pay attention that UIGetScreenImage is a private API, so it will be rejected. If you want to do something similar you can try to use -renderInContext on the window layer or -drawViewHierchyInRect(only ios7).
This method should be used as a category on UIView:
- (UIImage *) imageByRenderingViewOpaque:(BOOL) yesOrNO {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, yesOrNO, 0);
if ([self respondsToSelector:#selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
}
else {
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
}
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultingImage;
}
You have also this method that you can call on UIScree instance - (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates, but that will return only a view not an image.

Resources