I am interested in building a Collage style app for the IPhone and IPad. I have been looking at other apps and trying to work out the method that they use to create the final image.
I am guessing that the app has a UIView and then each individual image is a UIImageView and is a subview of the main UIView. The user is then able to move each UIImageView and position them as they intend.
Now my question is, after the user has positioned all the UIImageViews on screen how do you then create the final image from what is on the screen. This of course takes into account that you will be upscaling the images to create lets say an A4 sized final print.
Can anyone share some information?
Thanks
You should take a look at CGContext Reference. You can do something like the following to combine imageView 1 and 2 to imageView 3.
Sample Code :
UIGraphicsBeginImageContext(imageView1.image.size);
CGRect rect = CGRectMake(0, 0, imageView1.image.size.width, imageView1.image.size.height);
[imageView1.image drawInRect:rect];
[imageView2.image drawInRect:rect blendMode:kCGBlendModeScreen alpha:0.5];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[imageView3 setImage:resultingImage];
GoodLuck !!!
If you use an UIView to include more 2 Images to merge, that you can try to capture the view to be an image to use.
//Capture View to Image
-(UIImage *)captureImageFromView
{
UIView *theView = self; //self extends UIView
if( NULL != UIGraphicsBeginImageContextWithOptions )
{
UIGraphicsBeginImageContextWithOptions(theView.bounds.size, NO, 2.0f);
}
else
{
//iOS 4.0
UIGraphicsBeginImageContext(theView.frame.size);
}
[theView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *captureImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return captureImage;
}
//Merge 2 Images to be an Image.
-(UIImage *)mergeBaseImage:(UIImage *)_baseImage
underImage:(UIImage *)_underImage
matchBaseImageSize:(BOOL)_matchBaseImageSize
{
UIGraphicsBeginImageContext(_baseImage.size);
[_baseImage drawInRect:CGRectMake(0, 0, _baseImage.size.width, _baseImage.size.height)];
if( _matchBaseImageSize )
{
[_underImage drawInRect:CGRectMake(0, 0, _baseImage.size.width, _baseImage.size.height)];
}
else
{
[_underImage drawInRect:CGRectMake(0, 0, _underImage.size.width, _underImage.size.height)];
}
UIImage *_mergedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return _mergedImage;
}
Wish it can help you.
Related
I am working on App in which i need to give an cropping option. Once i select the image from camera or gallery it should open on editing page where we have Oval image with zooming & moving option. Once we click on apply the captured image should cropped in oval shape.
Now following screen is from aviary sdk. But it has square cropping & in need the cropping in oval shape. I tried to customise it but not able to do so.
Can anyone suggest me the easiest or the best suitable way to implement this.
Thanks.
- (UIImage *)croppedPhoto {
// For dealing with Retina displays as well as non-Retina, we need to check
// the scale factor, if it is available. Note that we use the size of teh cropping Rect
// passed in, and not the size of the view we are taking a screenshot of.
CGRect croppingRect = CGRectMake(imgMaskImage.frame.origin.x,
imgMaskImage.frame.origin.y, imgMaskImage.frame.size.width,
imgMaskImage.frame.size.height);
imgMaskImage.hidden=YES;
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(croppingRect.size, YES, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(croppingRect.size);
}
// Create a graphics context and translate it the view we want to crop so
// that even in grabbing (0,0), that origin point now represents the actual
// cropping origin desired:
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -croppingRect.origin.x, -croppingRect.origin.y);
[self.view.layer renderInContext:ctx];
// Retrieve a UIImage from the current image context:
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Return the image in a UIImageView:
return snapshotImage;
}
This type of masking you can perform or else you use the coco controls
.h file:-
#interface yourClass : UIImageView
#end
.m file:-
#import <QuartzCore/QuartzCore.h>
#implementation yourClass
- (void)awakeFromNib
{
[super awakeFromNib];
CALayer *mask = [CALayer layer];
mask.contents = (id)[[UIImage imageNamed:#"ovalMask.png"] CGImage];
CGSize size = self.frame.size;
mask.frame = CGRectMake(0, 0, size.width, size.height);
self.layer.mask = mask;
[self.layer setMasksToBounds:YES];
}
#end
In my app, the user is able to put stickers on top of a photo. When they go to save their creation, I do a screen grab and store it in a UIImage:
UIGraphicsBeginImageContextWithOptions(self.mainView.bounds.size, NO, [UIScreen mainScreen].scale);
[self.mainView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
(where self.mainView has a subview UIImageView which holds the photo, and another subview UIView which holds the stickers).
I am wondering, is it possible to do a screen shot in this manner, and maintain the resolution of the aforementioned photo?
The following will 'flatten' two UIImages into one while maintaining the resolution of the original image(s):
CGSize photoSize = photoImage.size;
UIGraphicsBeginImageContextWithOptions(photoSize, NO, 0.0);
CGRect photoRect = CGRectMake(0, 0, photoSize.width, photoSize.height);
// Add the original photo into the context
[photoImage drawInRect:photoRect];
// Add the sticker image with its upper left corner set to where the user placed it
[stickerImage drawAtPoint:stickerView.frame.origin];
// Get the resulting 'flattened' image
UIImage *flattenedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The above assumes photoImage and stickerImage are both instances of UIImage and stickerView is a UIView with containing the stickerImage and thus will be able to use the stickerView frame to determine its origin.
If you have multiple stickers, just iterate through the collection.
If you are looking to save an image of your current view then this might help you.
UIGraphicsBeginImageContext(self.scrollView.contentSize);
[self.scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = CGImageCreateWithImageInRect(finalImage.CGImage,
CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y,
scrollView.frame.size.width, scrollView.frame.size.height));
UIImage *screenImage = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
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?
I want to take screenshot programatically. So that i write code for it like,
CGContextRef context = [self createBitmapContextOfSize:self.frame.size];
//not sure why this is necessary...image renders upside-down and mirrored
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.frame.size.height);
CGContextConcatCTM(context, flipVertical);
[self.layer renderInContext:context];
CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIImage* background = [UIImage imageWithCGImage: cgImage];
CGImageRelease(cgImage);
self.currentScreen = background;
Here all code is in custom UIView of UIViewController. Now when i play UIImageView png sequence animation on UIView, then i didn't get updated changes in UIImageView which is subview of custom UIView, why? I got only result is UIImageView with first UIImage.
Basically i need to create an video of my game play like talking tom application.
Take the screenshot of your ImageView with something like this:
[[[yourImageView layer] presentationLayer] renderInContext:context];
Use NSTimer for calling that getScreenshot function.
Hope this helps
you should probably take a look at AVFoundation and specifically AVAssetWriter as a way of creating videos of your screen content.
Following code is use for the capture the image into the iPhone for that following code to be use.
CGRect rect = CGRectMake(0.0, 0.0,self.view.frame.size.width,self.view.frame.size.height-44);
NSValue *rectObj = [NSValue valueWithCGRect:rect];
CGRect rectRestored = [rectObj CGRectValue];
UIGraphicsBeginImageContext(CGSizeMake(rectRestored.size.width, rectRestored.size.height-44));
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
Also store the image into the gallery.
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];