4

I want to save 2 UIImages that are moved, resized and rotated by user. The problem is i dont want to use such function as any 'printscreen one', because it makes both images to lose a lot from their quality (resolution).

Atm i use something like this:

UIGraphicsBeginImageContext(image1.size);
[image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

However ofc it just adds two images, their rotation, resizing and moving isn't operated here. Can anybody help with considering these 3 aspects in coding? Any help is appreciated!

My biggest thanks in advance :)

EDIT: images can be rotated and zoomed by user (handling touch events)!

Dot NET
  • 4,891
  • 13
  • 55
  • 98
Nat
  • 12,032
  • 9
  • 56
  • 103

2 Answers2

4

You have to set the transform of the context to match your imageView's transform before you start drawing into it.

i.e.,

CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformScale(transform, 1.0, -1.0);

CGContextConcatCTM(context, transform);

// Draw the image into the context
CGContextDrawImage(context, CGRectMake(-imageView.image.size.width/2, -imageView.image.size.height/2, imageView.image.size.width, imageView.image.size.height), imageView.image.CGImage);

// Get an image from the context
rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];

and check out Creating a UIImage from a rotated UIImageView.

EDIT: if you don't know the angle of rotation of the image you can get the transform from the layer property of the UIImageView:

UIGraphicsBeginImageContext(rotatedImageView.image.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform transform = rotatedImageView.transform;
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(context, transform);

// Draw the image into the context
CGContextDrawImage(context, CGRectMake(0, 0, rotatedImageView.image.size.width, rotatedImageView.image.size.height), rotatedImageView.image.CGImage);

// Get an image from the context
UIImage *newRotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];

UIGraphicsEndImageContext();

You will have to play about with the transform matrix to centre the image in the context and you will also have to calculate a bounding rectangle for the rotated image or it will be cropped at the corners (i.e., rotatedImageView.image.size is not big enough to encompass a rotated version of itself).

Community
  • 1
  • 1
Magic Bullet Dave
  • 9,006
  • 10
  • 51
  • 81
  • I'm not sure but i think your method is working when you know what angle do you move your image. I don't know how user will rotate image, because he uses his thumbs to do so. – Nat Aug 24 '11 at 14:12
  • That is true for my code. I should also be possible to get the transform from the UIImageView. This is an affine transformation matrix the same as I am creating in the first few lines of code. The only difference I think is that UIView the y-axis crosses at the top of the screen, with CoreGrahics/Quartz the y-axis crosses at the bottom of the screen. I haven't tried it but you should be able to get the matrix from the view, apply the scale to it (line 4 above) and then draw into the context. Hope that makes sense. Dave – Magic Bullet Dave Aug 24 '11 at 17:09
  • Have tried this and it works - will add some more example code to my answer. – Magic Bullet Dave Aug 24 '11 at 17:34
  • +1 for 'You have to set the transform of the context to match your imageView's transform before you start drawing into it.' line... – hmdeep Oct 11 '14 at 06:46
0

Try this:

UIImage *temp = [[UIImage alloc] initWithCGImage:image1 scale:1.0 orientation: yourOrientation];
[temp drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];

Similarly for image2. Rotation and resizing are handled by orientation and scale respectively. yourOrientation is a UIImageOrientation enum variable and can have a value from 0-7(check this apple documentation on different UIImageOrientation values). Hope it helps...

EDIT: To handle rotations, just write the desired orientation for the rotation you require. You can rotate 90 deg left/right or flip vertically/horizontally. For eg, in the apple documentation, UIImageOrientationUp is 0, UIImageOrientationDown is 1 and so on. Check out my github repo for an example.

tipycalFlow
  • 7,594
  • 4
  • 34
  • 45
  • The different orientations are provided at the end of the apple documentations, the link for which is as above. – tipycalFlow Aug 17 '11 at 12:29
  • No, this is working wrong. My user can rotate image with 2-finger touch, same with rotating- user can do this. Your code rotates image as programmer wants, not user. I think i will have just to capture screen. Thank you very much for your idea and help tho! :) – Nat Aug 17 '11 at 12:46
  • oh...I got it. You'll have to use CGAffineTransformRotate method. check this one http://cl.ly/2Q3A1U261B253e1g2W1Q. It handles multi-touch and simultaneous rotation – tipycalFlow Aug 18 '11 at 05:26
  • Just instead of label, use imageView – tipycalFlow Aug 18 '11 at 05:59
  • I have my method to rotate, i just dont have a proper method to save rotated and zoomed image :) – Nat Aug 24 '11 at 10:10