Turning a UITableView into an UIImageView - iphone

I have got a UITableView, and I want to capture the visible portion of it, and put it into a UIImage. Any way of doing this?
EDIT
Self-answered below

Thanks for the replies. All of the answers would work with a UIView, but not with a UITableView - at least not when the table has scrolled. When scrolled, the captured image would appear black or transparent. I had tried similar solutions as the ones below before. I guess people assumed the answer was obvious, and that's why I was down-voted - for being naughty enough to ask such an obvious question.
Anyway, the real solution is that you have to use the table's contentOffset:
- (UIImage *) imageWithTableView:(UITableView *)tableView
{
UIView *renderedView = tableView;
CGPoint tableContentOffset = tableView.contentOffset;
UIGraphicsBeginImageContextWithOptions(renderedView.bounds.size, renderedView.opaque, 0.0);
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(contextRef, 0, -tableContentOffset.y);
[tableView.layer renderInContext:contextRef];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

UIGraphicsBeginImageContext(someView.bounds.size);
[someView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Taken from this question.

- (UIImage *)captureView {
//hide controls if needed
CGRect rect = [yourTableView bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[yourTableview.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}

UIGraphicsBeginImageContext(tableView.bounds.size);
[tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Maybe those posts will be helpful
Rendering UIView with its children
Saving UIView contents in iOS 4 with real size of the images inside (i.e. scale contentes up for save)
Safe way to render UIVIew to an image on background thread?

Related

How to take a screenshot programmatically in iOS?

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!
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;
}
-(UIImage *) screenshot
{
CGImageRef UIGetScreenImage(void);
CGImageRef screen = UIGetScreenImage();
UIImage* screenImage = [UIImage imageWithCGImage:screen];
CGImageRelease(screen); // you need to call this.
return screenImage;
}
Well, there are few ways of capturing the iPhone screen programmatically
Using UIKIT http://developer.apple.com/library/ios/#qa/qa1703/_index.html
Using AVFoundation framework http://developer.apple.com/library/ios/#qa/qa1702/_index.html
Using OpenGL ES
http://developer.apple.com/library/ios/#qa/qa1704/_index.html
Starting from iOS 7 you can also use Why does my programmatically created screenshot look so bad on iOS 7?
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();
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.
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;
}
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = [UIImagePNGRepresentation(image) retain];
UImage *screenShot = [UIImage imageWithData:data];
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.
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?
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);

UIImage screenshot loses its quality

I am merging two images and then I take a screenshot by applying this code:
UIGraphicsBeginImageContext(size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
img_AddText=viewImage;
[dragView removeFromSuperview];
imgV_SelectedImg.image=nil;
imgV_SelectedImg.image=img_AddText;
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
The problem is that when the final image loses its quality it blurs.
Try using the withOptions version of UIGraphicsBeginImageContext
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
i got the snapshot with good quality and particular location of screen. By this code.
-(UIImage *)takeScreenShot
{
CGRect grabRect;
grabRect = CGRectMake(0,70,320,260);
UIGraphicsBeginImageContextWithOptions(grabRect.size, self.view.opaque, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
[self.view.layer renderInContext:ctx];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
it gives me excellent snapshot..
I've made a category on UIImage class that may help you. It goes like this:
+ (UIImage*)imageWithView:(UIView *)view opaque:(BOOL)opaque bgColor:(UIColor*)bgColor{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, opaque, [[UIScreen mainScreen] scale]);
if(!opaque){
[bgColor set];
}
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
It works fine for me. No bluring was detected. Try to use it. If you'll still have it then most likely the problem is in your saving code...
Cheers... :)
UIGraphicsBeginImageContextWithOptions(size, NO, 2.0);
this solve my prblem by increasing scale from 1.0 to 2.0
Did you provide an image for retina display? You should check it. You might be running in a simulator (in retina).

Capturing CGRect does not give proper image. What to do?

I am capturing CGRect with following code. But the resulting image is not the image what i want. Image has some transparent background. What to do for removing transparent background as suggesting the picture.
- (UIImage *)captureScreenInRect:(CGRect)captureFrame {
CALayer *layer;
layer = imageScrollview.layer;
UIGraphicsBeginImageContext(imageScrollview.bounds.size);
CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
\[layer renderInContext:UIGraphicsGetCurrentContext()\];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenImage;
}
Translate your context so that its origin matches your captureFrame:
UIGraphicsBeginImageContext(imageScrollview.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, -captureFrame.origin.x, -captureFrame.origin.y);
[imageScrollView.layer renderInContext:c];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
(written from memory, untested)
Additionally clipping the context is not necessary as the image is already clipped by the image context's bounds.
Try this one
CGRect cropRect = CGRectMake(imageScrollview.frame.origin.x+15, imageScrollview.frame.origin.y+15, WIDTH, HEIGHT);

iPhone: UIImage obtained after rendering a view is solid black

I'm using this method to render a UIView into a UIImage:
+ (UIImage *)imageWithView:(UIView *)view {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
The resulting image is of the right size (as shown by the UIImage's size property), but its contents is solid black colour. The view passed there definitely contains some graphics, but it's not rendered. Any idea why?
This is the code I use to capture images of a UIView:
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
Your code looks fine to me. You can try swapping mine out to see if it helps, but I'd cite it to be a separate issue from the code you posted.

How to create an image from a UIView / UIScrollView

I have an image in an UIScrollView, that can be scrolled and zoomed.
When the user presses a button, I want the code to create an image from whatever part of the UIScrollView is inside an area I specify with a CGRect.
I've seen code to crop UIImages, but I can't adapt it to do the same for a view, because it uses CGContextDrawImage.
Any thoughts?
Cheers,
Andre
I've managed to get it.
Here's my solution, based on a few different ones from the web:
- (UIImage *)imageByCropping:(UIScrollView *)imageToCrop toRect:(CGRect)rect
{
CGSize pageSize = rect.size;
UIGraphicsBeginImageContext(pageSize);
CGContextRef resizedContext = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(resizedContext, -imageToCrop.contentOffset.x, -imageToCrop.contentOffset.y);
[imageToCrop.layer renderInContext:resizedContext];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
which you call by using:
CGRect clippedRect = CGRectMake(0, 0, 320, 300);
picture.image = [self imageByCropping:myScrollView toRect:clippedRect];