Basically I want to screenshot a UIView which is called CustomViewLayout, which belongs to MyClass. MyClass's view is assigned to NormalView. Therefore if I call self.view it will reference NormalView. I have made a property viewCustom which is an outlet for CustomViewLayout. Anyways, I want to screenshot CustomViewLayout, I have tried this:
UIGraphicsBeginImageContextWithOptions(self.viewCustom.bounds.size, self.viewCustom.opaque, 0.0);
[self.viewCustom.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
That image is then displayed/attached inside an In-App Mail (MFMailComposeViewController). And it doesn't work, it shows a blue box with a question mark inside, which I presume means the image is not readable. I know there is nothing wrong with my In-App Mail image attachment code because if I change my screenshot code to screenshot self.view like below:
UIGraphicsBeginImageContextWithOptions(self.viewCustom.bounds.size, self.viewCustom.opaque, 0.0);
[self.viewCustom.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
Then it works fine. So what should I do to screenshot my other view?
Thanks for the help!
The solution was just easily to load the different nib name from MyClass and then reload it back later.
Easy!
Related
I used the code below for years to be able to capture a screenshot of an UITableView (including hidden rows) and save it to the user's phone gallery or share it.
Since they updated to iOS 13 it doesn't work anymore, it captures only the visible part of the table leaving it blank on the bottom part.
-(UIImage *)imageFromCurrentTable
{
CGRect frame = self.tableView.frame;
frame.size.height = self.tableView.contentSize.height;
self.tableView.frame = frame;
UIGraphicsBeginImageContext(self.tableView.bounds.size);
[self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
return [UIImage imageWithData:data];
}
What changed in iOS 13? How this code can be updated? (the code is Obj-C but I will accept also swift answers!)
I have faced this issue. Due to cell Reuse, UIGraphicsGetImageFromCurrentImageContext cannot produce full UITableView structure.
One Way [Not Efficient Way]:
In cellForRowAtIndexPath, we can able to get which UITableViewCell using. Store that cell in [Int: UITableViewCell].
Get screenshot from UITableViewCell.contentView.
Add that screenshot's image as subview to UIView one by one.
Now, UIView having UITableView's contentView as Images.
Get screenshot from UIView.
if we add more than one View to imageView and NSString also. Is it possible to get image from ImageView that contain all images and strings etc?
like this
From what I understand in your question, you have added an ImageView for the building, another for the video symbol (as a subview) and a UILabel (again as a subview) for the time. You want all these to be rendered as a single UIImage. For this, you can use:
UIGraphicsBeginImageContext(imageView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[imageView.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The screenshot UIImage will contain your desired image.
Here's my code to get the screenshot of the view:
if (NULL != UIGraphicsBeginImageContextWithOptions){
UIGraphicsBeginImageContextWithOptions(pagedScrollView.frame.size, NO, [[UIScreen mainScreen] scale]);
}else{
UIGraphicsBeginImageContext(pagedScrollView.frame.size);
}
[pagedScrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithImage:screenshotImage];
imageView.frame = CGRectMake(imageView.frame.origin.x, imageView.frame.origin.y, imageView.frame.size.width, imageView.frame.size.height);
imageView.backgroundColor = [UIColor greenColor];
[self.view addSubview:imageView];
I'm 100% sure I have the right frame and the right view - the size of UIImageView say about it - but the thing is I can't get my UIImage to be displayed on the UIImageView.
The UIImageView is added on the view and I see a green region on it - but no image inside it, what can be wrong?
I'm using iOS 6 and ARC.
Well, I just tested your code running on my view controller's view and the capture and display worked fine. This leads me to believe that pagedScrollView is probably nil, or has a zero frame.
Either way, you'll be creating an image from a blank context and then passing it to your image view resulting in there not being any visible image.
It turns out I've been taking a screenshot of a long UIScrollView and I was always taking its first page - it had a lot of pages in it and sometimes the layer had nothing in it. It also turns out that UIImage was never released and the memory can effectively store dozens of them.
I have a program that fetches an image from the library, but I'm using code I found online to resize that image so that it can fit on the screen (basically making it 640x960), but then it would still be too big to display, so in another UIImage I'm copying the first resized image and re-resizing this one to make it about 1/4 of the screen (or 160x240). The code is this:
for ViewController.h:
UIImage *img;
UIImage *thumb;
-(UIImage*) scaleImage: (UIImage*)image toSize:(CGSize)newSize;
(this of course, is only the code related to my problem)
for ViewController.m
-(UIImage*) scaleImage: (UIImage*)image toSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
and in the same m file on another function, the scaleImage function is called when pressing a button with these lines:
[self scaleImage:img toSize:CGSizeMake(640, 960)];
thumb = img;
[self scaleImage:thumb toSize:CGSizeMake(160, 240)];
In the project I've previously been able to successfully provide an image for img using [info objectForKey:UIImagePickerControllerOriginalImage]; which would be the image chosen from the library. I've already "file owned" everything so that this function takes place (and it does because I create an UIAlert within it and it shows, and a NSLog to print out when scaleImage starts and it does, twice), but the image is never re-sized!! Does anyone know why?? Please let me know, thank you for anyone who comments with help or suggestions!!
Your scaleImage method returns the scaled image, for example
thumb = [self scaleImage:img toSize:CGSizeMake(640, 960)];
I'm working on something that will create an email and attach an image of the screen for the user to send. I'm using the following code to create and attach the image.
UIGraphicsBeginImageContext([self.view frame].size);
[[self.view layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext([self.view bounds].size);
[myImage drawInRect:CGRectMake(0, 0, [self.view bounds].size.width,[self.view bounds].size.height)];
myImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(myImage);
[mailer addAttachmentData:imageData mimeType:#"image/jpg" fileName:#"blah"];
However, this includes all of the subviews, and I want to exclude a toolbar and a segmented view, leaving only the view above the toolbar and the text field in that view. I've tagged all the relevant views and subviews, but how do I use those tags to create an image that includes what I want and excludes what I don't want?
Before you render the image, set all the views you don't want to show to hidden.
I have several apps that do this exact same thing, and that's what I do.
renderInContext and related functions basically take a screenshot, so WYSIWYG