I want to merge 2 image in 2 UIImageView into 1 image with "correct" position, angle, ratio scale as I see on screen.
In my project, there are 2 UIImageView
- imageView is the main UIImageView
- topImageView is the overlay UIImageView that can be drag, rotate, scale
I can save image merged by draw 2 images but wrong position, angle, ratio scale.
This is my code:
UIImage *img = topImageView.image;
UIImage *bottomImg = self.imageView.image;
CGSize bounds = self.imageView.image.size;
UIGraphicsBeginImageContext(bounds);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, topImageView.image.size.width * 0.5, topImageView.image.size.height * 0.5);
CGFloat angle = atan2(topImageView.transform.b, topImageView.transform.a);
CGContextRotateCTM(ctx, angle);
[topImageView.image drawInRect:CGRectMake(-topImageView.image.size.width * 0.5,
-topImageView.image.size.height * 0.5,
topImageView.image.size.width,
topImageView.image.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(bounds);
[bottomImg drawInRect:CGRectMake(0, 0, bounds.width, bounds.height)];
[newImage drawInRect:CGRectMake(topImageView.frame.origin.x,
topImageView.frame.origin.y,
newImage.size.width,
newImage.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Any idea to help me? Thanks a lot!
Add both of those images as subviews to a UIView. Do what you need to the images and then take a snapshot of the UIVIew like so:
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *MergedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Try This
#pragma mark - Marge two Images
- (UIImage *) addImageToImage:(UIImage *)img withImage2:(UIImage *)img2{
CGSize size = CGSizeMake(imageView.image.size.width, imageView.image.size.height);
UIGraphicsBeginImageContext(size);
CGPoint pointImg1 = CGPointMake(0,0);
[img drawAtPoint:pointImg1];
CGPoint pointImg2 = CGPointMake(0,0);
[img2 drawAtPoint: pointImg2];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
[self addImageToImage:imageView.image withImage2:imageView2.image];
Related
I want to rotate image (arrow) in circular path in coreGraphics like this image. in circular path.
input image:
output after rotation:
This will return rotated image
- (UIImage *)rotateImage:(UIImage *)image onDegrees:(float)degrees
{
CGFloat rads = M_PI * degrees / 180;
float newSide = MAX([image size].width, [image size].height);
CGSize size = CGSizeMake(image.size.width, newSide);
UIGraphicsBeginImageContext(size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, image.size.width, newSide/2);
CGContextRotateCTM(ctx, rads);
CGRect r = CGRectMake(0,-[image size].height/2,image.size.width,image. size.height);
[image drawInRect:r];
UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return i;
}
UIImage *arrowRotated180 = [self rotateImage:[UIImage imageNamed:#"arrowImage"] onDegrees:180];
UIImage *arrowRotated90 = [self rotateImage:[UIImage imageNamed:#"arrowImage"] onDegrees:90];
Put three images and rotate 2 & 3 image as follow.
imageview2.transform = CGAffineTransformMakeRotation(M_PI/4);
imageview3.transform = CGAffineTransformMakeRotation(M_PI/2);
Hope this will help you...
try UIcollectionview it worked my case .
After going through this link, issue with my code is that output image is unable to set proper x and y values as cropped image seems to have 0 and 0 in the resultant image irrespective to where I zoom (or where the scroll offset is calculated). Here's what I tried.
- (IBAction)crop:(id)sender
{
float zoomScale = 1.0f / [self.scroll zoomScale];
CGRect rect;
NSLog(#"contentOffset is :%f,%f",[self.scroll contentOffset].x,[self.scroll contentOffset].y);
rect.origin.x = self.scroll.contentOffset.x * zoomScale;
rect.origin.y = self.scroll.contentOffset.y * zoomScale;
rect.size.width = self.scroll.bounds.size.width * zoomScale;
rect.size.height = self.scroll.bounds.size.height * zoomScale;
UIGraphicsBeginImageContextWithOptions( CGSizeMake(rect.size.width, rect.size.height),
NO,
0.);
NSLog(#"rect offset is :%f,%f",rect.origin.x,rect.origin.y);
CGPoint point = CGPointMake(-rect.origin.x, -rect.origin.y); **//even though above NSLog have some values, but output image is unable to set proper x and y values as cropped image seems to have 0 and 0 in the resultant image.**
[[self.imagV image] drawAtPoint:point
blendMode:kCGBlendModeCopy
alpha:1];
self.croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
DTImageViewController *imageViewController = [[DTImageViewController alloc] initWithNibName:#"DTImageViewController" bundle:nil];
imageViewController.image = self.croppedImage;
[self.navigationController pushViewController:imageViewController animated:YES];
}
Similar code as already posted but just taking whole UIScrollView bounds without passing a CGRect
-(void)takeScreenShotOfScrollView
{
UIGraphicsBeginImageContextWithOptions(scrollView.bounds.size, YES, [UIScreen mainScreen].scale);
CGPoint offset = scrollView.contentOffset;
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -offset.x, -offset.y);
[scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
img = [SDImageHelper imageWithImage:img_image scaledToSize:CGSizeMake(769, 495)];
}
BONUS:
The cropping method
+(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
//UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
I'm using the following code for this and it does exactly what expected:
- (UIImage *) croppedImageOfView:(UIView *) view withFrame:(CGRect) rect
{
UIGraphicsBeginImageContextWithOptions(rect.size,NO,0.0);
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -rect.origin.x, -rect.origin.y);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *visibleScrollViewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return visibleScrollViewImage;
}
- (void) crop
{
CGRect neededRect = CGRectMake(50,50,100,100);
UIImage *image = [self croppedImageOfView:_scrollView withFrame:neededRect];
}
Works well even if content is zoomed, the only thing that must be calculated wisely is needed area CGRect.
Hi in my iOS application I want to rotate the UIImage data in 90 Degrees.
I used the below code for 180 degree rotation - and it works fine.
- (UIImage*)upsideDownBunny:(UIImage *)img {
CGSize imgSize = [img size];
UIGraphicsBeginImageContext(imgSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextRotateCTM(context, M_PI);
CGContextTranslateCTM(context, -imgSize.width, -imgSize.height);
[img drawInRect:CGRectMake(0, 0, imgSize.width, imgSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
But when I try to rotate in 90 degree it is not working - please correct me
- (UIImage *)upsideDownBunny:(UIImage *)img {
CGSize imgSize = [img size];
UIGraphicsBeginImageContext(imgSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextRotateCTM(context, M_PI_2);
CGContextTranslateCTM(context, -imgSize.width, -imgSize.height);
[img drawInRect:CGRectMake(0, 0, imgSize.width, imgSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Try this...
UIImage * LandscapeImage = [UIImage imageNamed: imgname];
UIImage * PortraitImage = [[UIImage alloc] initWithCGImage: LandscapeImage.CGImage
scale: 1.0
orientation: UIImageOrientationLeft];
hope this helps you!
Try this
- (UIImage *)upsideDownBunny:(UIImage *)image {
// Rotate in degrees
CGFloat degrees = M_PI_2;
// Calculate the size of the rotated view's containing box for our drawing space
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
CGAffineTransform transform = CGAffineTransformMakeRotation(degrees);
rotatedViewBox.transform = transform;
CGSize rotatedSize = rotatedViewBox.frame.size;
// Create image context
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef context = UIGraphicsGetCurrentContext();
// Move the origin to the middle of the image.
CGContextTranslateCTM(context, rotatedSize.width * 0.5f, rotatedSize.height * 0.5f);
// Rotate the image context
CGContextRotateCTM(context, degrees);
// Now, draw the rotated/scaled image into the context
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(-image.size.width * 0.5f, -image.size.height * 0.5f, image.size.width, image.size.height), [image CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
The problem is your context is being rotated around (0,0) which is the top left corner and after 90 degrees rotate it will go out of bounds. So you need to move the origin of the context to middle.
I am using the following code to convert the contents of a UIView to a PNG image:
UIGraphicsBeginImageContext(myView.bounds.size);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This works fine. If the UIView is 500 pixels high, and I'd like to generate two images (one of the top half and one of the bottom half), how would I go about doing this?
Any help would be greatly appreciated.
There are a few ways you could do this. One way is to draw it into one big image, then make two sub-images:
static UIImage *halfOfImage(UIImage *fullImage, CGFloat yOffset) {
// Pass yOffset == 0 for the top half.
// Pass yOffset == 0.5 for the bottom half.
CGImageRef cgImage = fullImage.CGImage;
size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);
CGRect rect = CGRectMake(0, height * yOffset, width, height * 0.5f);
CGImageRef cgSubImage = CGImageCreateWithImageInRect(cgImage, rect);
UIImage *subImage = [UIImage imageWithCGImage:cgSubImage scale:fullImage.scale
orientation:fullImage.imageOrientation];
CGImageRelease(cgSubImage);
return subImage;
}
...
UIGraphicsBeginImageContext(myView.bounds.size);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *topHalfImage = halfOfImage(viewImage, 0);
UIImage *bottomHalfImage = halfOfImage(viewImage, 0.5f);
i have 2 images: first one is the user personal image, the second one is an icon (badge).
i want to add the second uiimage (icon) on the bottom left corner of the first uiimage (user's image) and save them into a new Uiimage.
thanks
Try this method:
-(UIImage *)drawImage:(UIImage*)profileImage withBadge:(UIImage *)badge
{
UIGraphicsBeginImageContextWithOptions(profileImage.size, NO, 0.0f);
[profileImage drawInRect:CGRectMake(0, 0, profileImage.size.width, profileImage.size.height)];
[badge drawInRect:CGRectMake(0, profileImage.size.height - badge.size.height, badge.size.width, badge.size.height)];
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
You can use it by:
UIImage *myBadgedImage = [self drawImage:profileImage withBadge:badgeImage];
Try this:
CGFloat scale = [self currentScale];
if (scale > 1.5)
UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, scale);
else
UIGraphicsBeginImageContext(view.frame.size);
[image1 drawInRect:CGRectMake(0, 0, w1, h1)];
[image2 drawInRect:CGRectMake(0, 0, w2, h2)];
UIImage* screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();