Taking a screenshot of a view that is currently not on screen on iOS - ios

I'm trying to make a transition between two ViewControllers. My Transition class has a property for the destination view controller. When I try to get a screenshot of the destination's view, I use this method:
+ (UIImage *)renderImageFromView:(UIView *)view withRect:(CGRect)frame {
// Create a new context the size of the frame
UIGraphicsBeginImageContextWithOptions(frame.size, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// Render the view
[view.layer renderInContext:context];
// Get the image from the context
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
// Cleanup the context you created
UIGraphicsEndImageContext();
return renderedImage;
}
So when I want the image, I'll do this:
UIImage *image = [UIImage renderImageFromView:destinationController.view withRect:destinationController.view.bounds];
I tried it on a blank UIViewController with an orange background color and a label. I get the orange background color, but I do not get the label that was created in IB. Is there a way to get a proper screenshot of the new view I plan on showing? Thanks!

You need to make sure the view's layer is drawn to first. Calling renderInContext on a CALayer will only recursively call additional child CALayers. You need your child UIViews to draw themselves, not just using the CALayer.
Try calling
[view drawrect:frame];
instead of
[view.layer renderInContext:context];
As long as you have an open graphics context(which you do at that point), drawrect should draw directly into that.

Related

UIView to UIImage with layer borders

I have a UIView whose layer has two sublayers, each of which has a 1.5 pixel border around the outside. I am trying to create a UIImage from this view with the following code
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0f);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
The code does return a UIImage, but the image is clipped – that is, the image doesn't include the all of the borders on the sublayers. I've tried tweaking the sizes/bounds but to no effect. Any suggestions of what else I might try?
Thanks!
What happens if you send the parent layer a
drawInContext: message instead of telling the view to draw itself?

iOS7's drawViewHierarchyInRect doesn't work?

From what I've read, iOS7's new drawViewHierarchyInRect is supposed to be faster than CALayer's renderInContext. And according to this and this, it should be a simple matter of calling:
[myView drawViewHierarchyInRect:myView.frame afterScreenUpdates:YES];
instead of
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
However, when I try this, I just get blank images. Full code that does the capture, where "self" is a subclass of UIView,
// YES = opaque. Ignores alpha channel, so less memory is used.
// This method for some reasons renders the
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, self.window.screen.scale); // Still slow.
if ( [AIMAppDelegate isOniOS7OrNewer] )
[self drawViewHierarchyInRect:self.frame afterScreenUpdates:YES]; // Doesn't work!
else
[self.layer renderInContext:UIGraphicsGetCurrentContext()]; // Works!
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
contentImageView.image = image; // this is empty if done using iOS7's way
and contentImageView is a UIImageView that is added as a subView to self during initialization.
Additionally, the drawing that I want captured in the image is contained in other sub-views that are also added to self as a sub-view during initialization (including contentImageView).
Any ideas why this is failing when using drawViewHierarchyInRect?
* Update *
I get an image if I draw a specific sub-view, such as:
[contentImageView drawViewHierarchyInRect:contentImageView.frame afterScreenUpdates:YES];
or
[self.curvesView drawViewHierarchyInRect:self.curvesView.frame afterScreenUpdates:YES];
however I need all the visible sub-views combined into one image.
Try it with self.bounds rather than self.frame—it’s possible you’re getting an image of your view rendered outside the boundaries of the image context you’ve created.

How to save 2 UIImageView in one image to cameraroll

I have two UIImageView one over the other, and I'dlike to save them in one single file to camera roll.
UIImageWriteToSavedPhotosAlbum(self.myimage.image,nil,nil,nil);
});
the images are laying on top of each other and are the same size. the top one has few alpha in order to see the other one
you can do it in this way..,
Add your both imageview in one UIView., and then take screenshot of This UiView and stored generated image in your desired destination.
Here is Code to take screen shot by coding
// code to take Screen shot
-(void) takeScreenshot
{
// Replace self.view with your view name which containing your ImageViews
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:context];
// get a UIImage from the image context
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
// clean up drawing environment
UIGraphicsEndImageContext();
// Then save your Image in your desired destination
}
Hope it will Help you, Happy Coding

Render layer of UIView which is not in the View Hierarchy

What i want to achieve is to take an image of an UIView which has not been added as a subview, present and do stuff with the image and afterwards add the view to the view hierarchy.
I've searched and tried now for a while and believe, that it is simply not possible.
Obviously the problem is, that the view hasn't been drawn (called drawRect: i guess) if it hasn't been added as a subview.
Actually i thought renderInContext: would call drawRect/layer on its own.
It isn't even enough to add it as subview right before draw it to an imageContext because it won't be rendered immediately.
I take the screenshot with renderInContext: with the layer of the view, see my code here:
[self.view addSubView:view];
UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -frame.origin.x, -frame.origin.y);
[view.layer renderInContext:context];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
So my question is, has anybody managed to render a not visible UIView and if how?
Well this is awkward.
After a mail conversation with a very kind apple dev support, we reviewed my code and we noticed that i simply set the hidden property to YES. - Just don't do that.
So it is straight forward to make a screenshot of a view which is not in the view hierarchy.
It was total my fault why it didn't work.
Try to addd UIView to hierarchy but keep it hidden.
- (void)takeScreenSnapshot {
UIView *capturedView = self.view;
UIView *hiddenView = self.hiddeniew; // hidden view which is
// a part of capturedView
hiddenView.hidden = NO;
BOOL retina = [self isRetinaDisplay];
UIImage *image = [capturedView captureImageWithScale:(retina) ? 2.f : 1.f];
hiddenView.hidden = YES;
}

Iphone sdk save drawings without whole context

I want to capture screen of my view from my iPhone app. I have white background view and on that I draw a lines on that view's layer using this method .
- (void)draw {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
if (self.fillColor) {
[self.fillColor setFill];
[self.path fill];
}
if (self.strokeColor) {
[self.strokeColor setStroke];
[self.path stroke];
}
CGContextRestoreGState(context);
}
- (void)drawRect:(CGRect)rect {
// Drawing code.
for (<Drawable> d in drawables) {
[d draw];
}
[delegate drawTemporary];
}
I have use delegate methods to draw lines on layer.
This is the project link from where I get help for this.
https://github.com/search?q=dudel&type=Everything&repo=&langOverride=&start_value=1
Now when I use the following context methods to save the drawing only I successfully save it without that white background.
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
But When I use the following method of Bezier Pathe I cannot save the drawing without its white background,It saves the whole screen i.e. that drawing and its background.
UIGraphicsBeginImageContext(self.view.bounds.size);
[dudelView.layer renderInContext:UIGraphicsGetCurrentContext()];
//UIImage *finishedPic = UIGraphicsGetImageFromCurrentImageContext();
So can anybody help me how can I save the drawing only here in this app.
(You've tagged this as MapKit related, but make no mention of MapKit.)
Why don't you just split your drawing sequence into three chunks?
Draw your paths into an image context and get a UIImage, as you described.
Draw a background color.
Draw the UIImage.
Then you can use the UIImage for your "screenshot" as well.
I should also note that if the only thing you don't want in your captured UIImage is the background color, you are better off creating a UIImageView, setting its background color (-setBackgroundColor:), and setting its image to be your UIImage.
UIImageView internally has a number of optimizations that allow it to display graphics with much higher performance than you can get with a custom -drawRect: implementation.
Why don't you just save the drawables array? Those are all the drawings without the underlying image :)

Resources