Need to create a snapshot of a view at runtime - iphone

i need to take a snapshot of my current ipad-view. That view loads and plays a video.
I found this function which works almost really well.
- (UIImage*)captureView:(UIView *)view {
CGRect rect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
(Source from: LINK)
The problem is, that the current frame of the playing video is not captured, only the view but without video-content. Do i forgot to update the display or anything else before saving the image? Is there a special function that reads the latest screen-values?
Thanks for your time and help.

Have you tried using the UIGetScreenImage() function?
It's private, but Apple allows to use it, so your app will be validated for the App Store, even if you use it.
You just need to declare its prototype, so the compiler won't complain:
CGImageRef UIGetScreenImage( void );
Note: you can create a NSImage from the CGImageRef with the following NSImage method:
- ( id )initWithCGImage: ( CGImageRef )cgImage size:( NSSize )size;

Related

How can I get a LIVE screenshot programmatically, when my App is running?

I just want to share a screen shoot of an UIView vie email, FB or what ever users want!
The below code only takes a original of UIView with no inputed texts nor changed images
CGRect rect = [mainView bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[mainView.layer renderInContext:context];
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
You should be able to use one of the solutions at this answer depending on whether it's a retina device or not.

Non-null invalid context error when creating a UIImage from a UIView

I'm using the following to generate a UIImage from a UIView
UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
which usually works but about half the time, I get this error when renderInContext is called:
<Error>: CGContextDrawImage: invalid context 0x84d0b20
Does anyone have any idea why this happens or how to even detect when it happens? I think I would feel better if the address for the context was 0x0 because it would at least be something I could test for and deal with but this so far this has me stumped.
Edit: Whoops. Meant to use view.frame.size and not view.bounds.size.
If you create a context with width or height zero, the context will be invalid. This could happen if the view size is zero on either axis, or if the view is nil.
Also, since you're rendering a layer, you might want to get the layer bounds and scale, instead of the view bounds and screen scale. Most of the time these values will be the same, but it's good to allow for the times they are not.
// Debugging output to see how if an invalid context is being created due to zero size.
NSLog(#"View = %#", view);
NSLog(#"View size = %#", NSStringFromCGSize(view.bounds.size));
UIGraphicsBeginImageContextWithOptions(view.layer.bounds.size, YES, view.layer.contentsScale);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I had a similar issue but was able to solve it by pushing and popping the image context prior to my layer rendering its contents.
Try something like this:
UIImage *snapshotImage = nil;
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, view.layer.contentsScale);
{
CGContextRef imageContext = UIGraphicsGetCurrentContext();
if (imageContext != NULL) {
UIGraphicsPushContext(imageContext);
{
[view.layer renderInContext:imageContext];
}
UIGraphicsPopContext();
}
snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();
For what it's worth, there are alternative (and more efficient) ways to obtain a snapshot but it's still under NDA.
UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Hope, this will help you....

How can I save a photo of part of the screen to the local iPhone's Photos?

I have put a UILabel that the user has chosen over a UIImageView that was also chosen by the user. I would like to put these two into a picture, kind of like a screenshot of a small part of the screen. I have absolutely no idea how to do this and have no experience in this. Any help is appreciated!!
You could setup a Bitmap context with a clipping mask of the area you want to save. Then you use the backing layer's renderInContext method to draw onto that context.
CGSize imageSize = CGSizeMake(960, 580);
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToRect(context, CGRectMake(10,10,200,200); // whatever rect you want
[self.layer renderInContext:context];
UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Save to camera roll
UIImageWriteToSavedPhotosAlbum(myImage, self, #selector(didSaveImage), null);

iphone sdk: UIScrollView as Image

I want to save the content of an UiScrollView as an Image. It seems that it is not as easy as the UIImageRepresentation that can be used for Views or ImageViews, anyone an idea how to do it?
I usually use a method implemented in a category:
+ (UIImage *)screenshot:(UIView *)view {
UIGraphicsBeginImageContext(view.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CALayer *layer = view.layer;
[layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
but, in your case, I suppose it will not suit well if your need is to get the whole content (also the part not visible in that moment). You could change the zoom value and then take the screenshot if it's a good enough solution.

Create a UIImage from two other UIImages on the iPhone

I'm trying to write an animation on the iPhone, without much success, getting crashes and nothing seems to work.
What I wanna do appears simple, create a UIImage, and draw part of another UIImage into it, I got a bit confused with the context and layers and stuff.
Could someone please explain how to write something like that (efficiently), with example code?
For the record, this turns out to be fairly straightforward - everything you need to know is somewhere in the example below:
+ (UIImage*) addStarToThumb:(UIImage*)thumb
{
CGSize size = CGSizeMake(50, 50);
UIGraphicsBeginImageContext(size);
CGPoint thumbPoint = CGPointMake(0, 25 - thumb.size.height / 2);
[thumb drawAtPoint:thumbPoint];
UIImage* starred = [UIImage imageNamed:#"starred.png"];
CGPoint starredPoint = CGPointMake(0, 0);
[starred drawAtPoint:starredPoint];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
I just want to add a comment about the answer above by dpjanes, because it is a good answer but will look blocky on iPhone 4 (with high resolution retina display), since "UIGraphicsGetImageFromCurrentImageContext()" does not render at the full resolution of an iPhone 4.
Use "...WithOptions()" instead. But since WithOptions is not available until iOS 4.0, you could weak link it (discussed here) then use the following code to only use the hires version if it is supported:
if (UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
}
else {
UIGraphicsBeginImageContext();
}
Here is an example to merge two images that are the same size into one. I don't know if this is the best and don't know if this kind of code is posted somewhere else. Here is my two cents.
+ (UIImage *)mergeBackImage:(UIImage *)backImage withFrontImage:(UIImage *)frontImage
{
UIImage *newImage;
CGRect rect = CGRectMake(0, 0, backImage.size.width, backImage.size.height);
// Begin context
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
// draw images
[backImage drawInRect:rect];
[frontImage drawInRect:rect];
// grab context
newImage = UIGraphicsGetImageFromCurrentImageContext();
// end context
UIGraphicsEndImageContext();
return newImage;
}
Hope this helps.