Merging multiple image into single image - ios

I want to merge multiple images into single image while saving to camera roll.
Actually,I'm having different images in different views.I'm having 3 images in one view and also 4 images when selecting layout with 4 frames.someone help me how to merge them.
my sharing code:
CGRect rect=[self.previewView bounds];
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
CGSize size=CGSizeMake(self.previewView.frame.size.width, self.previewView.frame.size.height);
if(selectButtonTag==2)
{
[self.doubleFrameViewcapturedImg1.image drawInRect:CGRectMake(0, 0, size.width, size.height)blendMode:kCGBlendModeNormal alpha:0.5];
[self.doubleFrameViewcapturedImg2.image drawInRect:CGRectMake(0,0,size.width,size.height) blendMode:kCGBlendModeNormal alpha:0.5];
}
CGContextRef context=UIGraphicsGetCurrentContext();
[self.previewView.layer renderInContext:context];
UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSArray *activity=[[NSArray alloc]initWithObjects:UIActivityTypeCopyToPasteboard,
UIActivityTypeMail,
UIActivityTypeMessage,
UIActivityTypePostToFacebook,
UIActivityTypePostToTwitter,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAirDrop
, nil];
UIActivityViewController *ShareView=[[UIActivityViewController alloc]initWithActivityItems:#[newImage,activity] applicationActivities:nil];
ShareView.popoverPresentationController.sourceView=self.view;
[self presentViewController:ShareView animated:YES completion:nil];

you can do this by using CoreGraphics,for more details just follow the tutorial by CodeTutePlus AdvancedImageTechnicsCoreGraphics

Related

snapshotViewAfterScreenUpdates on UIScreen gives blank snapshot on device

I'm trying to get an image of the entire screen as the user sees it. The following code should work however it will only work in the simulator. What do I have to do to get this to work on a device running iOS 8.1?
UIView *snapshot = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:YES];
CGSize outputSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
UIGraphicsBeginImageContextWithOptions(outputSize, NO, 0);
[snapshot drawViewHierarchyInRect:CGRectMake(0.0, 0.0, outputSize.width, outputSize.height) afterScreenUpdates:YES];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Happy to try alternative strategies but the key is I want it as the user sees it - keyboards and all.
Cheers
UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)), NO, 1.0f);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)) afterScreenUpdates:NO];
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();

Capturing (animated) screen behind UIView

I asked a similar question recently on how to add a translucent effect to a UIView and got a good response.
However it used a lot of CPU power to process so I used some of the ideas behind the answer but did the filtering using GPUImage which is much more efficient.
It works well for a static screen, but I want to change the background UIImageView's image with an animation. However when I set the UIView to sample the background during the transition, it seems to ignore the transition and show the new Image before the animation has started.
The relevant code is as follows (ask if you need more!):
The superview containing the custom UIView and the UIImageView background:
//The Transition
[contentView setScheduled:YES]; //Starts the sampling every 0.2 seconds
//bg is the UIImageView and contentView is the 'translucent' UIView subclass
[UIView transitionWithView:bg duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
[bg setImage:newImage];
}completion:^(BOOL finished){
[contentView setScheduled:NO];
}];
Then in the UIView subclass:
- (UIImage *)snapshotOfSuperview:(UIView *)superview
{
CGFloat scale = 0.5;
if (([UIScreen mainScreen].scale > 1 || self.contentMode == UIViewContentModeScaleAspectFill))
{
CGFloat blockSize = 12.0f/5;
scale = blockSize/MAX(blockSize * 2, floor(self.blurRadius));
}
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -self.frame.origin.x, -self.frame.origin.y);
self.hidden=YES; //Don't take a snapshot of the view
[superview.layer renderInContext:context];
self.hidden=NO;
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
-(void)updateViewBG{
UIImage *superviewImage = [self snapshotOfSuperview:self.superview];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
GPUImageGaussianBlurFilter* filter = [[GPUImageGaussianBlurFilter alloc] init];
filter.blurSize = 0.8f;
UIImage* newBG = [self applyTint:self.tintColour image:[filter imageByFilteringImage:superviewImage]];
dispatch_async(dispatch_get_main_queue(), ^{
self.layer.contents = (id)newBG.CGImage;
self.layer.contentsScale = newBG.scale;
});
});
}
-(UIImage*)applyTint:(UIColor*)colour image:(UIImage*)inImage{
UIImage *newImage;
if (colour) {
UIGraphicsBeginImageContext(inImage.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, inImage.size.width, inImage.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);
CGContextSaveGState(ctx);
CGContextClipToMask(ctx, area, inImage.CGImage);
[colour set];
CGContextFillRect(ctx, area);
CGContextRestoreGState(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeLighten);
CGContextDrawImage(ctx, area, inImage.CGImage);
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}else{
newImage = inImage;
}
return newImage;
}
-(void)displayLayer:(CALayer *)layer{
[self updateViewBG];
}
How can I get the background to follow the animation?
I think the problem is that as soon as you change the image, displayLayer is called (disregarding the transition being in progress) and thus the new image is used for the translucency.
You should modify updateViewBG so that it does not update the layer content before the transition is finished. E.g., you could add a flag to your class, set it when you start the transition and reset it when it completes. When the flag is set you do not call updateViewBG.
[UIView transitionWithView:bg duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
self.isTransitionInProgress = YES;
[bg setImage:newImage];
}completion:^(BOOL finished){
[contentView setScheduled:NO];
self.isTransitionInProgress = NO;
[contentView.layer setNeedsDisplay];
}];
-(void)displayLayer:(CALayer *)layer{
if (!self.isTransitionInProgress)
[self updateViewBG];
}

I am taking a screenshot in my application. but now I want to take it by specifying the x and y coordinate. I mean taking a screenshot from y=40

Now i am posting screen shot in facebook. but i am trying to define screenshot height.
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *imgPicture = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if ([SLComposeViewController isAvailableForServiceType: SLServiceTypeFacebook]) {
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controller setInitialText :#"post from my iphone"];
[controller addURL:[NSURL URLWithString:#"https://www.facebook.com/birjesh.sharma.921"]];
//[controller addImage:[UIImage imageNamed:imgPicture]];
[controller addImage:imgPicture];
[self presentViewController: controller animated:YES completion:nil];
}
try this
UIGraphicsBeginImageContext(self.view.bounds.size);
// retrieve the current graphics context
CGContextRef context = UIGraphicsGetCurrentContext();
// render view into context
[self.view.layer renderInContext:context];
// create image from context
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
image=[self cropImage:image];
UIGraphicsEndImageContext();
- (UIImage *)cropImage:(UIImage *)oldImage {
CGSize imageSize = oldImage.size;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageSize.width,imageSize.height-10),NO,0.); //you can set your height and width
[oldImage drawAtPoint:CGPointMake( 0, -40) blendMode:kCGBlendModeCopy alpha:1.];//you can set your own value X and Y
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}

Screenshot to post twitter sheet

I am working on my application to add twitter feature to share the screenshot of my current viewcontroller. Is there any in built method that I can use ?
This answer has the following method to create a screenshot:
- (UIImage *)captureView:(UIView *)view {
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);
[view.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
It returns a UIImage, which you can then use like this:
SLComposeViewController *tweetSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
tweetSheet.image = [self captureView:self.view]; // or self.navigationController.view
[self presentViewController:tweetSheet animated:YES completion:^{}];

Snapshot of View Doesn't Render

I'm trying to get a snapshot of another controller's view to use in an animation. I'm using the following code, but I see nothing but the background color of that view, and none of its subviews (two buttons, a text view, and a label):
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
FirstPageController *fpController = [self.storyboard instantiateViewControllerWithIdentifier:#"FirstPage"];
UIGraphicsBeginImageContext(fpController.view.bounds.size);
NSLog(#"%#",fpController.view.subviews);
[fpController.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGSize destinationSize = CGSizeMake(90, 122);
UIGraphicsBeginImageContext(destinationSize);
[viewImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.imageView2 = [[UIImageView alloc] initWithImage:newImage];
self.imageView2.center = self.view.center;
[self.view addSubview:self.imageView2];
NSLog(#"%#",NSStringFromCGSize(self.imageView2.image.size));
}
I've logged all the relevant things, the fpController, the imageView, the image, and all are logging correctly.
After Edit: If I switch to the current controller's view, it works fine, so I'm thinking that this has to do with getting a snapshot of a view that's not on screen. Can that be done?
Hope this will help you:
CGSize textcontent =CGSizeMake(width, height);
UIGraphicsBeginImageContext(textcontent);
if ([UIScreen instancesRespondToSelector:#selector(scale)] && [[UIScreen mainScreen] scale] == 2.0f)
{
UIGraphicsBeginImageContextWithOptions(textcontent, YES, 1.0f);
}
else
{
UIGraphicsBeginImageContext(textcontent);
}
[image.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
UIGraphicsBeginImageContextWithOptions(fpController.view.bounds.size, NO, 0.0);
UIGraphicsBeginImageContextWithOptions(destinationSize, NO, 0.0);
Use this two lines instead of UIGraphicsBeginImageContext(fpController.view.bounds.size);
UIGraphicsBeginImageContext(destinationSize); respectively
hope it help's you
I found one way to make this work, though it seems like a hack. I add the view I want to render as a subview of my view, do the rendering, and then remove the view. It is never seen on screen, so visually, it's fine. I just wonder whether there's a better way.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.fpController = [self.storyboard instantiateViewControllerWithIdentifier:#"FirstPage"];
[self.view insertSubview:self.fpController.view belowSubview:self.view];
UIGraphicsBeginImageContext(self.fpController.view.bounds.size);
[self.fpController.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.fpController.view removeFromSuperview];
self.imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 90, 122)];
self.imageView2.image = viewImage;
[self.pageView insertSubview:self.imageView2 belowSubview:self.imageView];
}

Resources