Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I mirror a UIImage picture from UIImagePickerController

I'm trying to figure out if there is any way to mirror an image. For example, take a picture of someone's face and then cut it in half and show what their face looks like with each side mirrored. There doesn't seem to be any tricks like this in CGAffineTransform functions. Graphics experts please help!!!

like image 604
Terry Avatar asked Jun 27 '10 23:06

Terry


3 Answers

The basic "trick" here is to use a scaling transform about the X or Y axis with a factor of -1. For example, you could use this to create a "flip about the horizontal axis" transform:

CGAffineTransform transform = CGAffineTransformScale(transform, -1, 1);

Then you can set the transform property on a UIImageView to flip the assigned image, or concatenate it with another transform to do more sophisticated effects. To get the exact effect you described, you may need to write some custom drawing code to draw your original image into a context, then overlay the flipped half on top of it. This is relatively straightforward in Core Graphics.

like image 89
warrenm Avatar answered Nov 15 '22 20:11

warrenm


If you only plan on supporting 4.0+

UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored;
switch (image.imageOrientation) {
  case UIImageOrientationUp: break;
  case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break;
  // ...
}
UIImage * flippedImage = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:flippedOrientation];
like image 19
tc. Avatar answered Nov 15 '22 20:11

tc.


You may think, why bother with the outrageously long switch statement?

? UIImage *flip = [UIImage imageWithCGImage:image.CGImage   
?                                     scale:image.scale
?                               orientation:(image.imageOrientation + 4) % 8];

And if you take a look at the enum you can see that modular arithmetic would do:

typedef NS_ENUM(NSInteger, UIImageOrientation) {
    UIImageOrientationUp,            // default orientation
    UIImageOrientationDown,          // 180 deg rotation
    UIImageOrientationLeft,          // 90 deg CCW
    UIImageOrientationRight,         // 90 deg CW
    UIImageOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip
    UIImageOrientationDownMirrored,  // horizontal flip
    UIImageOrientationLeftMirrored,  // vertical flip
    UIImageOrientationRightMirrored, // vertical flip
};

But this code is too clever. You should write a function with an explicit switch statement instead. E.g.

UIImageOrientation mirroredImageOrientation(UIImageOrientation orientation) {
    switch(orientation) {
        case UIImageOrientationUp: return UIImageOrientationUpMirrored;
        case UIImageOrientationDown: return UIImageOrientationDownMirrored;
        case UIImageOrientationLeft: return UIImageOrientationLeftMirrored;
        case UIImageOrientationRight: return UIImageOrientationRightMirrored;
        case UIImageOrientationUpMirrored: return UIImageOrientationUp;
        case UIImageOrientationDownMirrored: return UIImageOrientationDown;
        case UIImageOrientationLeftMirrored: return UIImageOrientationLeft;
        case UIImageOrientationRightMirrored: return UIImageOrientationRight;
        default: return orientation;
    }
}

And use the function like this:

UIImage *flip = [UIImage imageWithCGImage:image.CGImage   
                                    scale:image.scale
                              orientation:mirroredImageOrientation(image.imageOrientation)];

I've added question marks to indicate questionable, smelly code. Similar to The Practice of Programming

like image 12
sabalaba Avatar answered Nov 15 '22 20:11

sabalaba