I've got two UIImageView: the first one is laying on the top of the other (eg. an overlay).
I want now to take a screenshot of the whole thing.
Note that before that step, I allow the user to change the overlay by panning,scaling and ROTATING it, so I must keep track of his editing.
So, here's the homework:
rotating the context basing on the view's transform rotation value
positioning on the origin, where the user finished to pan the overlay
calculate the size of the overlay view (it's always a rectangle, however!)
I'm gonna merge them inside a similar piece of code:
UIGraphicsBeginImageContext...
...
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
but... what does "best fit" instead of the "..."?
Example code is well accepted!
Thanks
UIGraphicsBeginImageContext(firstImage.size);
[firstImage drawAtPoint:CGPointMake(0,0)];
[secondImage drawAtPoint:CGPointMake(0,0)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Related
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?
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.
I have an oversized image loaded in a image view that goes out of bounds both vertically and horizontally.
The end user can scroll around the image (the oversized imageview is in a scrollview) and when they find an area that they like I would like to crop out the area of the image that is shown on the screen. (much like a screenshot but only of the imageview.image I'm then going to put that into a different Imageview.
I can't seem to work out how to accomplish the "screenshot" of the area of the image view's image that is currently showing on the screen.
You can use CGImageCreateWithImageInRect to create a subimage of the displayed image. Use contentOffset and the scrollViews bounds to create the rect from which you want to create the image.
CGRect rect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, CGRectGetWidth(scrollView.bounds), CGRectGetHeight(scrollView.bounds));
CGImageRef subImageRef = CGImageCreateWithImageInRect([originalImage CGImage], rect);
If you zoom your scrollView you will need to take the zoomLevel into account too.
I ended up using the following code to achieve what I was looking for to grab the image. Thank you to Karl for his input and a thank you to iNoob whom answer to a previous question [Located here on StackOverflow][1] I used for mine.
Just use the below code to take a "screenshot" just set anything you don't want in the image to.hidden = True; before the code to hide it from the screenshot and set them to .Hidden = FALSE; after the code to bring them back.
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
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
I have a drawing app where you have one UIImageView that serves as the "drawing layer." You have another UIImageView beneath it that is the "image layer," containing the image you are drawing on. I like having this separation. However, I want the user to be able to "save and email" the drawing they have made on top of the image as one unified image. How do I do this?
Your UIImageView instances must be part of a UIView hierachy so all you need to do is paint that top containing UIView into a context
UIGraphicsBeginImageContext(CGSizeMake(width, height));
[container.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *fimage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
or if that gives you trouble successively paint the two images into a context
UIGraphicsBeginImageContext(CGSizeMake(width, height));
[image1.layer renderInContext:UIGraphicsGetCurrentContext()];
[image2.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *fimage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
from there you can write the data where you choose
NSData *data = UIImagePNGRepresentation(fimage);
Pass that data into the MailComposer setup.