348

I am testing my iPhone application on an iOS 3.1.3 iPhone. I am selecting/capturing an image using a UIImagePickerController:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];
[self.navigationController presentModalViewController:imagePicker animated:YES];
[imagePicker release];



- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
    imageView.image = self.image;
    [self.navigationController dismissModalViewControllerAnimated:YES];
    submitButton.enabled = YES;
}

I then at some point send it to my web server using the ASI classes:

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://example.com/myscript.php"]];
[request setDelegate:self];
[request setStringEncoding:NSUTF8StringEncoding];
[request setShouldContinueWhenAppEntersBackground:YES];
//other post keys/values
[request setFile:UIImageJPEGRepresentation(self.image, 100.0f) withFileName:[NSString stringWithFormat:@"%d.jpg", [[NSDate date] timeIntervalSinceNow]] andContentType:@"image/jpg" forKey:@"imageFile"];
[request startAsynchronous];

the problem: when i take a picture with the iphone while holding it landscape, the image gets uploaded to the server and it viewed like you would expect. when taking a picture holding the phone in portrait, the image is uploaded and viewed as it had been rotated 90 degrees.

my application is set to only work in portrait modes(upsidedown and regular).

How can i make the image always show the correct orientation after uploading?

the image appears to be correct as displayed in an UIImageView(directly after taking the picture), but viewing on the server says otherwise.

Alok
  • 24,880
  • 6
  • 40
  • 67
james
  • 26,141
  • 19
  • 95
  • 113

20 Answers20

515

A UIImage has a property imageOrientation, which instructs the UIImageView and other UIImage consumers to rotate the raw image data. There's a good chance that this flag is being saved to the exif data in the uploaded jpeg image, but the program you use to view it is not honoring that flag.

To rotate the UIImage to display properly when uploaded, you can use a category like this:

UIImage+fixOrientation.h

@interface UIImage (fixOrientation)

- (UIImage *)fixOrientation;

@end

UIImage+fixOrientation.m

@implementation UIImage (fixOrientation)

- (UIImage *)fixOrientation {

    // No-op if the orientation is already correct
    if (self.imageOrientation == UIImageOrientationUp) return self;

    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (self.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationUpMirrored:
            break;
    }

    switch (self.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationDown:
        case UIImageOrientationLeft:
        case UIImageOrientationRight:
            break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                             CGImageGetBitsPerComponent(self.CGImage), 0,
                                             CGImageGetColorSpace(self.CGImage),
                                             CGImageGetBitmapInfo(self.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
            break;
    }

    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

@end
Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
Anomie
  • 92,546
  • 13
  • 126
  • 145
  • 9
    thanks, worked perfect. never used a category or understood them until now! – james Mar 26 '11 at 12:33
  • Your answer helped me a lot. I was so confused about this strange behavior while uploading photo. I changed server side, I modified my code, I manually changed orientation & I also tried many different ways. But none of them worked. Your solution helped me a lot. Thank you. – sagarkothari Jul 07 '11 at 13:01
  • so basically I need to call this after pulling the image from the server right? I did that and it didn't work out for me... – adit Sep 20 '11 at 23:14
  • How can i integrate to my file?[image fixOrientation] is it correct? – vinay Oct 14 '11 at 06:30
  • hmm i seem to be having a problem with this fixing the issue on iOS 5. can you confirm that this works on iOS 5 too? – james Nov 15 '11 at 14:14
  • yeah, that works on iOS 5. For @Anomie: TYVM! I can't upvote this enough times to show how thankful I am :) – Novarg Jan 10 '12 at 15:37
  • Is there a way to modify this to fix all UIImageOrientation to have UIImageOrientationLeft as up? I tried and my mileage didn't go far at all so I thought I would ask. – avelis Jan 19 '12 at 00:24
  • @Anomie u are my god! You have no idea what your answer has done for me! I wanna repeat thank you for 1 thousand times!! – Wang Liang Mar 08 '12 at 07:40
  • Please update the code to take `scale` into account, otherwise it will not work for 2x images. – an0 May 16 '12 at 01:57
  • @an0: If I ever get back into iOS programming, perhaps I will. It should theoretically just be a manner of multiplying `self.size.width` and `self.size.height` by `self.scale` wherever they appear (or really, storing the products in local vars and using those local vars wherever needed) and then using `imageWithCGImage:scale:orientation:` (with `UIImageOrientationUp` as the orientation) to create the UIImage at the end, but I'm not in a position to test it right now. – Anomie May 27 '12 at 14:40
  • 1
    @Anomie It's hard for me to explain how happy you just made me. Your answer saved my day. Thank you very much. – Darkshore Grouper Aug 21 '12 at 23:39
  • 3
    I tried the same, works perfect but it taking appx 2-3 seconds to rotate 3264*2448 resolution images. So please suggest improved version. – Laxmi Lal Menaria Dec 18 '12 at 13:07
  • for love of god, how to do you use this function in your code? - (UIImage *)fixOrientation??? I tried this but it doesn;t work UIImage *img1 = fixOrientation(image); – Sam B Jan 05 '13 at 20:31
  • 1
    @SamBudda you need to create a new objective-c class with the name "UIImage+fixOrientation", then in the .h and .m files, copy/paste the above code. Import it into any class that will use the fix orientation function (e.g. #import "UIImage+fixOrientation.h" at the top of your class), then call it like so [imageToOrient fixOrientation]. [Here's apples guide](http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html) – StoriKnow Mar 08 '13 at 15:31
  • 3
    I consider http://stackoverflow.com/questions/8915630/ios-uiimageview-how-to-handle-uiimage-image-orientation a better answer – pojomx Apr 02 '13 at 21:34
  • 2
    There is yet another solution to this problem [here](http://stackoverflow.com/questions/20204495/mfmailcomposeviewcontroller-image-orientation) (quite similar to this one) that includes a lengthy discussion of what's actually going on. – Gallymon Nov 29 '13 at 04:30
  • @pojomx Which answer? you linked to a question – William Entriken Dec 16 '13 at 04:30
  • I've been struggiling with this issue all evening. So thanks for this awesome answer. Marry me. – GeneCode Jan 04 '14 at 11:41
  • oh, Sorry, it was Tommy's, you rotate the picture regardless its original orientation – pojomx Apr 22 '14 at 21:57
  • @pojomx the answer you mentioned is not working after upload to windows backend. but Tommy [comment](http://stackoverflow.com/questions/8915630/ios-uiimageview-how-to-handle-uiimage-image-orientation#comment12214179_8915809) explains how to rotate image data which confirm an0 answer. I ended using an0 answer cuz its short and faster. – Jawad Al Shaikh Apr 28 '14 at 08:53
  • Just want to add something, that this method will mess up the OpenGL texture load if you load it using [GLKTextureLoader textureWithCGImage:[image fixOrientation].CGImage]. The right approach seems to be from this one http://blog.logichigh.com/2008/06/05/uiimage-fix/ Although I don't know why. – Coolant May 13 '14 at 13:31
  • 1
    This approach is consuming 50MB of memory for a 5MB image, causing infrequent memory related crashes. I highly advise choosing @an0's method. – Yerk Mar 09 '15 at 19:25
  • @Yerk I'm using a fresh project with a live stream of the camera and in the bottom a collection view previewing all the photos the user takes and my memory is below 5 MB for the whole duration (even taking 20+ photos very fast) using this solution. The solution shown is releasing correctly there are no memory leaks/issues here. I would look elsewhere for the problem. – Drmorgan May 20 '15 at 15:37
  • This doesn't work for me on swift. For some reason all my image has .Right orientation no matter in which orientation its taken in – user3526002 Jul 13 '15 at 16:00
  • I needed to replace CGImageGetBitmapInfo(self.CGImage) ... with ... (CGBitmapInfo)kCGImageAlphaPremultipliedLast ... because I was getting errors on CGBitmapContextCreate. I think Apple changed something on iOS 9 because I did not have this problem before. – xaphod Apr 29 '16 at 20:30
243

I figured out a much simpler one:

- (UIImage *)normalizedImage {
    if (self.imageOrientation == UIImageOrientationUp) return self; 

    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    [self drawInRect:(CGRect){0, 0, self.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

BTW: @Anomie's code does not take scale into account, so will not work for 2x images.

an0
  • 17,191
  • 12
  • 86
  • 136
  • How do you use it in the code? I have this one: UIImageJPEGRepresentation(image, 90); where the image is an UIImage – Dejell Sep 04 '12 at 20:11
  • 2
    @Odelya Add this method to your UIImage category then call [image normalizedImage]. Or use the code of the method directly by replacing `self` with your UIImage object. – an0 Sep 04 '12 at 20:26
  • 1
    @an0 The method takes about a second which consumes time. Is there a way to improve it? – Dejell Mar 03 '13 at 15:05
  • This seems like the simplest solution, and it worked for me on iOS 6. Runs pretty fast, too. – Pat McG Jun 16 '13 at 21:42
  • When I take pictures with the camera on the iPad I upload them and the orientation gets messed up, your code fixed that. Thanks a lot! – Pieter Gunst Jul 19 '13 at 09:17
  • 1
    Thanks for that.From my tests it look like this method is a bit faster than the chosen answer, something like 20% on my iphone4. – chrisben Aug 29 '13 at 15:52
  • 7
    There is yet another solution to this problem [here](http://stackoverflow.com/questions/20204495/mfmailcomposeviewcontroller-image-orientation) along with a lengthy explanation of what's going on. – Gallymon Nov 29 '13 at 04:25
  • Looks like when the photo is taken when the device is in FaceUp or FaceDown direction (capturing something that is placed on a desk or floor), the image is getting rotated to wrong orientation. For example, if I rotate the device from portrait to landscape when the device is still in FaceUp direction, the captured photo is in portrait mode instead of landscape mode. I ran into this issue in iOS-7 and solved it by tracking the device orientation (not view orientation) and rotating the image to required orientation. Rotation is done using NYXImagesKit. – Prabu Arumugam Apr 01 '14 at 23:50
  • In what case will the iOS camera/image-picker give you a 2x image? – aroth May 27 '14 at 05:19
  • [This Swift version](http://stackoverflow.com/a/34648079) also preserves image transparency (or lack thereof). – user2067021 Jan 09 '16 at 22:26
129

Here is a Swift version of the answer by @an0:

func normalizedImage() -> UIImage {

  if (self.imageOrientation == UIImageOrientation.Up) { 
      return self;
  }

  UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
  let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
  self.drawInRect(rect)

  let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext();
  return normalizedImage;
}

Also in a more general function:

func fixOrientation(img:UIImage) -> UIImage {

  if (img.imageOrientation == UIImageOrientation.Up) { 
      return img;
  }

  UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
  let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
  img.drawInRect(rect)

  let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext();
  return normalizedImage;

}

Swift 3 version:

func fixOrientation(img: UIImage) -> UIImage {
    if (img.imageOrientation == .up) {
        return img
    }

    UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
    let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
    img.draw(in: rect)

    let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return normalizedImage
}
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
prajna
  • 1,629
  • 1
  • 17
  • 18
  • 10
    Rare that you need to scroll all the way to the bottom for the best answer. +1! – sudo make install May 30 '15 at 22:55
  • where should i use fixOrientation? I have a saveImage function, should i use it there or on my imageHolder.image? – alex Oct 23 '15 at 08:13
  • If you want to use the more general function above then yes you could use it in your saveImage function. Just pass fixOrientation your UIImage object and it will return a correctly oriented version of the UIImage you passed into it. – prajna Oct 25 '15 at 22:03
  • 1
    Thanks for the Swift 3 version – Shadros Jun 07 '18 at 06:52
44

Solution for Swift 3.1 for orientation issue while capturing the image from Camera.

I have updated the solution given by jake and Metal Heart

UIImage extension

//MARK:- Image Orientation fix

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform: CGAffineTransform = CGAffineTransform.identity

        if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: CGFloat(Double.pi))
        }

        if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
        }

        if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: 0, y: self.size.height);
            transform = transform.rotated(by: CGFloat(-Double.pi / 2.0));
        }

        if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        }

        if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: self.size.height, y: 0);
            transform = transform.scaledBy(x: -1, y: 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                                      bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                                      space: self.cgImage!.colorSpace!,
                                                      bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!;

        ctx.concatenate(transform)

        if ( self.imageOrientation == UIImageOrientation.left ||
            self.imageOrientation == UIImageOrientation.leftMirrored ||
            self.imageOrientation == UIImageOrientation.right ||
            self.imageOrientation == UIImageOrientation.rightMirrored ) {
            ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.height,height: self.size.width))
        } else {
            ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.width,height: self.size.height))
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(cgImage: ctx.makeImage()!)
    }
}

Swift 2.0

//MARK:- Image Orientation fix

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.Up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform: CGAffineTransform = CGAffineTransformIdentity

        if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
        }

        if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
        }

        if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform,  CGFloat(-M_PI_2));
        }

        if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
        }

        if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
            CGImageGetBitsPerComponent(self.CGImage), 0,
            CGImageGetColorSpace(self.CGImage),
            CGImageGetBitmapInfo(self.CGImage).rawValue)!;

        CGContextConcatCTM(ctx, transform)

        if ( self.imageOrientation == UIImageOrientation.Left ||
            self.imageOrientation == UIImageOrientation.LeftMirrored ||
            self.imageOrientation == UIImageOrientation.Right ||
            self.imageOrientation == UIImageOrientation.RightMirrored ) {
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
        } else {
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)
    }
}

Use of this UIImage Extension in your code:

let fixOrientationImage=chosenImage.fixOrientation()

place this in your delegate methods of image picker like this

Swift 3.1

//MARK: Image Picker Delegates
    func imagePickerController(
        _ picker: UIImagePickerController,
        didFinishPickingMediaWithInfo info: [String : Any]){
        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        profileImg.contentMode = .scaleAspectFill
        let fixOrientationImage=chosenImage.fixOrientation()
        profileImg.image = fixOrientationImage

        dismiss(animated: true, completion: nil)
    }

Swift 2.0

//MARK: Image Picker Delegates
    func imagePickerController(
        picker: UIImagePickerController,
        didFinishPickingMediaWithInfo info: [String : AnyObject])
    {
        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        profileImg.contentMode = .ScaleAspectFill
        **//Fix the image orientation**
         let fixOrientationImage=chosenImage.fixOrientation()
        profileImg.image = fixOrientationImage

        dismissViewControllerAnimated(true, completion: nil)
    }
pgb
  • 24,813
  • 12
  • 83
  • 113
Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
  • 3
    Thanks, this helped me a lot. – kevinrodriguez-io Nov 24 '15 at 00:59
  • Its work. but I wonder is there any approach that can avoid calling the CG related API, as that caused leads to a large amount of memory allocation. It will only be released when we no longer retain the UIImage. – Tony Fung Mar 14 '17 at 07:01
  • 1
    This was working fine up until iOS 10. In iOS 11 after performing this I am getting a black image in return. I have made a small change (replaced M_PI with Double.pi) though. I am using XCode 9 with Swift 3.2. – Mahbub Morshed Oct 29 '17 at 08:55
31

Swift 4.x/5.0 version of @an0 's solution:

extension UIImage {
    func upOrientationImage() -> UIImage? {
        switch imageOrientation {
        case .up:
            return self
        default:
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            draw(in: CGRect(origin: .zero, size: size))
            let result = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return result
        }
    }
}
wzso
  • 3,482
  • 5
  • 27
  • 48
25

in swift ;)

UPDATE SWIFT 3.0 :D

func sFunc_imageFixOrientation(img:UIImage) -> UIImage {


    // No-op if the orientation is already correct
    if (img.imageOrientation == UIImageOrientation.up) {
        return img;
    }
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    var transform:CGAffineTransform = CGAffineTransform.identity

    if (img.imageOrientation == UIImageOrientation.down
        || img.imageOrientation == UIImageOrientation.downMirrored) {

        transform = transform.translatedBy(x: img.size.width, y: img.size.height)
        transform = transform.rotated(by: CGFloat(M_PI))
    }

    if (img.imageOrientation == UIImageOrientation.left
        || img.imageOrientation == UIImageOrientation.leftMirrored) {

        transform = transform.translatedBy(x: img.size.width, y: 0)
        transform = transform.rotated(by: CGFloat(M_PI_2))
    }

    if (img.imageOrientation == UIImageOrientation.right
        || img.imageOrientation == UIImageOrientation.rightMirrored) {

        transform = transform.translatedBy(x: 0, y: img.size.height);
        transform = transform.rotated(by: CGFloat(-M_PI_2));
    }

    if (img.imageOrientation == UIImageOrientation.upMirrored
        || img.imageOrientation == UIImageOrientation.downMirrored) {

        transform = transform.translatedBy(x: img.size.width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)
    }

    if (img.imageOrientation == UIImageOrientation.leftMirrored
        || img.imageOrientation == UIImageOrientation.rightMirrored) {

        transform = transform.translatedBy(x: img.size.height, y: 0);
        transform = transform.scaledBy(x: -1, y: 1);
    }


    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    let ctx:CGContext = CGContext(data: nil, width: Int(img.size.width), height: Int(img.size.height),
                                  bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                  space: img.cgImage!.colorSpace!,
                                  bitmapInfo: img.cgImage!.bitmapInfo.rawValue)!

    ctx.concatenate(transform)


    if (img.imageOrientation == UIImageOrientation.left
        || img.imageOrientation == UIImageOrientation.leftMirrored
        || img.imageOrientation == UIImageOrientation.right
        || img.imageOrientation == UIImageOrientation.rightMirrored
        ) {


        ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width))

    } else {
        ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height))
    }


    // And now we just create a new UIImage from the drawing context
    let cgimg:CGImage = ctx.makeImage()!
    let imgEnd:UIImage = UIImage(cgImage: cgimg)

    return imgEnd
}
MetalHeart2003
  • 372
  • 4
  • 8
  • After weeks of struggling with this issue and trying several other solutions, this one ended up working perfectly. If I could up vote +10 I would. Thank you. :) – SirNod Mar 14 '15 at 23:36
  • @MetalHeart2003 this method MASSIVELY increases the file size of my image, Mine went from 200kb to 4mb, is there any way to stop this happening? – TimWhiting Apr 01 '15 at 10:41
  • 2
    @TimWhiting it sounds like you are starting with a compressed image. But this method redraws the rotated image without any compression. You can recompress the bitmap image afterwards with UIImageJPEGRepresentation() – Richard Venable May 13 '15 at 18:54
12

I used this page when designing my app that takes pictures and I found that the following method will correct the orientation and use less memory and processor than previous answers:

CGImageRef cgRef = image.CGImage;
image = [[UIImage alloc] initWithCGImage:cgRef scale:1.0 orientation:UIImageOrientationUp];

This basically just rewraps the actual image data with a new orientation. I was using @an0's code but it makes a new image in memory which can be taxing on a 3264x2448 image that you might get from a camera.

Erroneous
  • 535
  • 4
  • 12
  • 1
    I tested this answer with iOS 7.1 on iPhone 5s but it didn't work, in which windows machines [MS-Paint, Win photo Viewer] and UIImageView showed the image with 90 degree orientation from original! note that images taken with default camera touch button, not the volume up. – Jawad Al Shaikh Apr 28 '14 at 08:37
  • 3
    seems like this just changes the orientation flag...needs to rotate the actual bits – hamsterdam May 29 '14 at 21:21
11

If you enable editing, then the edited image (as opposed to the original) will be oriented as expected:

UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.allowsEditing = YES;
// set delegate and present controller

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *photo = [info valueForKey:UIImagePickerControllerEditedImage];
    // do whatever
}

Enabling editing allows the user to resize and move the image before tapping "Use Photo"

Jon
  • 462
  • 5
  • 14
7

I achieve this by writing below a few lines of code

extension UIImage {

    public func correctlyOrientedImage() -> UIImage {
        guard imageOrientation != .up else { return self }

        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        draw(in: CGRect(origin: .zero, size: size))
        let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return normalizedImage
    }
}
emrcftci
  • 3,355
  • 3
  • 21
  • 35
sushmit yadav
  • 79
  • 2
  • 3
6

This what I have found for fixing orientation issue

UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);

UIImage *tempImage = [UIImage imageWithData:data];
UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
                                     scale:initialImage.scale
                               orientation:self.initialImage.imageOrientation];
initialImage = fixedOrientationImage;

EDIT:

UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);

initialImage = [UIImage imageWithCGImage:[UIImage imageWithData:data].CGImage
                                                     scale:initialImage.scale
                                               orientation:self.initialImage.imageOrientation];
Shekhar Gupta
  • 6,206
  • 3
  • 30
  • 50
  • 2
    Too much conversion between image to PNG back to image, making way too expensive. @an0 answer is better. – lxcid Aug 27 '13 at 07:27
5

Here’s a solution that doesn’t change the colorspace of the original image. If you want to normalize the orientation of a grayscale image, you are out of luck with all solutions based on UIGraphicsBeginImageContextWithOptions because it creates a context in the RGB colorspace. Instead, you have to create a context with the same properties as the original image and draw:

extension UIImage {
    static let rotatedOrentations: [UIImage.Orientation] = [.left, .leftMirrored, .right, .rightMirrored]

    func normalizedImage() -> UIImage {
        if imageOrientation == .up {
            return self
        }

        let image = self.cgImage!
        let swapOrientation = UIImage.rotatedOrentations.contains(imageOrientation)
        let width = swapOrientation ? image.height : image.width
        let height = swapOrientation ? image.width : image.height
        let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: image.colorSpace!, bitmapInfo: image.bitmapInfo.rawValue)!
        let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height));
        context.concatenate(flipVertical)
        UIGraphicsPushContext(context)
        self.draw(at: .zero)
        UIGraphicsPopContext()

        return UIImage(cgImage: context.makeImage()!)
    }
}
0xced
  • 25,219
  • 10
  • 103
  • 255
4

Update for Swift 3.1 based on Sourabh Sharma's answer, with code clean up.

extension UIImage {
    func fixedOrientation() -> UIImage {
        if imageOrientation == .up { return self }

        var transform:CGAffineTransform = .identity
        switch imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: size.height).rotated(by: .pi)
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: size.width, y: 0).rotated(by: .pi/2)
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
        default: break
        }

        switch imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: size.height, y: 0).scaledBy(x: -1, y: 1)
        default: break
        }

        let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
                                       bitsPerComponent: cgImage!.bitsPerComponent, bytesPerRow: 0,
                                       space: cgImage!.colorSpace!, bitmapInfo: cgImage!.bitmapInfo.rawValue)!
        ctx.concatenate(transform)

        switch imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.height,height: size.width))
        default:
            ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width,height: size.height))
        }
        return UIImage(cgImage: ctx.makeImage()!)
    }
}

Picker delegate method example:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    guard let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
    let fixedImage = originalImage.fixedOrientation()
    // do your work
}
Yaroslav
  • 2,435
  • 1
  • 19
  • 36
3

Here's UIImage extension for swift:

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.Up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform: CGAffineTransform = CGAffineTransformIdentity

        if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
        }

        if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
        }

        if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform,  CGFloat(-M_PI_2));
        }

        if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
        }

        if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        var ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
            CGImageGetBitsPerComponent(self.CGImage), 0,
            CGImageGetColorSpace(self.CGImage),
            CGImageGetBitmapInfo(self.CGImage));

        CGContextConcatCTM(ctx, transform)

        if ( self.imageOrientation == UIImageOrientation.Left ||
            self.imageOrientation == UIImageOrientation.LeftMirrored ||
            self.imageOrientation == UIImageOrientation.Right ||
            self.imageOrientation == UIImageOrientation.RightMirrored ) {
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
        } else {
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(CGImage: CGBitmapContextCreateImage(ctx))!
    }
}

Based on MetalHeart2003's earlier work..

jake1981
  • 303
  • 3
  • 11
3

Here is an UIImage extension in Swift 2 based on the accepted answer by @Anomie. It uses a clearer switch case. It also takes the optional value returned by CGBitmapContextCreateImage() into consideration.

extension UIImage {
    func rotateImageByOrientation() -> UIImage {
        // No-op if the orientation is already correct
        guard self.imageOrientation != .Up else {
            return self
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform = CGAffineTransformIdentity;

        switch (self.imageOrientation) {
        case .Down, .DownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))

        case .Left, .LeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))

        case .Right, .RightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))

        default:
            break
        }

        switch (self.imageOrientation) {
        case .UpMirrored, .DownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)

        case .LeftMirrored, .RightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)

        default:
            break
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
            CGImageGetBitsPerComponent(self.CGImage), 0,
            CGImageGetColorSpace(self.CGImage),
            CGImageGetBitmapInfo(self.CGImage).rawValue)
        CGContextConcatCTM(ctx, transform)
        switch (self.imageOrientation) {
        case .Left, .LeftMirrored, .Right, .RightMirrored:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }

        // And now we just create a new UIImage from the drawing context
        if let cgImage = CGBitmapContextCreateImage(ctx) {
            return UIImage(CGImage: cgImage)
        } else {
            return self
        }
    }
}
fantaghirocco
  • 4,761
  • 6
  • 38
  • 48
elegance66
  • 41
  • 3
3

I have experienced this issue with images taken from camera or saved in camera roll which are taken from camera. Images downloaded in photo library from safari browser does not rotate when uploaded.

I was able to solve this issue by making the image data as JPEG before uploading.

let image = info[UIImagePickerControllerOriginalImage] as! UIImage        
let data = UIImageJPEGRepresentation(image, 1.0)

We can now use the data for uploading and the image will not get rotated after upload.

Hope this will work.

Teena nath Paul
  • 2,219
  • 23
  • 28
1

If I understand, what you want to do is disregard the orientation of the UIImage? If so then you could do this:-

//image is your original image
image = [UIImage imageWithCGImage:[image CGImage]
                             scale:[image scale]
                       orientation: UIImageOrientationUp];

or in Swift :-

image = UIImage(CGImage: image.CGImage!, scale: image.scale, orientation:.Up)

It solved my cropping issue.. Hope, this is what you're looking for..

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
0

Swift 3 version based on @jake1981 who've taken it from @MetalHeart2003

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.

        var transform: CGAffineTransform = CGAffineTransform.identity

        if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: CGFloat(M_PI))
        }

        if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: CGFloat(M_PI_2))
        }

        if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: 0, y: self.size.height);
            transform = transform.rotated(by: CGFloat(-M_PI_2));
        }

        if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        }

        if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: self.size.height, y: 0);
            transform = transform.scaledBy(x: -1, y: 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                       bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                       space: self.cgImage!.colorSpace!,
                                       bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!
        ctx.concatenate(transform)

        if ( self.imageOrientation == UIImageOrientation.left ||
            self.imageOrientation == UIImageOrientation.leftMirrored ||
            self.imageOrientation == UIImageOrientation.right ||
            self.imageOrientation == UIImageOrientation.rightMirrored ) {

            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width))
        } else {
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(cgImage: ctx.makeImage()!)

    }
}
Faisal
  • 857
  • 2
  • 10
  • 21
0
@an0, thanks for the answer!
The only thing is autoreleasepool: 

func fixOrientation(img: UIImage) -> UIImage? {

    let result: UIImage?
    if img.imageOrientation == .up {
        result = img
    } else {

        result = autoreleasepool { () -> UIImage? in
            UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
            let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
            img.draw(in: rect)

            let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return normalizedImage
        }
    }

    return result
}
0

Here is the Swift-4.2 code for automatic fix your image orientation Returns UIImage

func AutofixImageOrientation(_ image: UIImage)->UIImage {

    UIGraphicsBeginImageContext(image.size)

    image.draw(at: .zero)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return newImage ?? image
}
Prashanth Thota
  • 157
  • 1
  • 11
0

I transposed this into Xamarin:

private static UIImage FixImageOrientation(UIImage image)
    {
        if (image.Orientation == UIImageOrientation.Up)
        {
            return image;
        }

        var transform = CGAffineTransform.MakeIdentity();

        float pi = (float)Math.PI;

        switch (image.Orientation)
        {
            case UIImageOrientation.Down:
            case UIImageOrientation.DownMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
                transform = CGAffineTransform.Rotate(transform, pi);
                break;

            case UIImageOrientation.Left:
            case UIImageOrientation.LeftMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                transform = CGAffineTransform.Rotate(transform, pi / 2);
                break;

            case UIImageOrientation.Right:
            case UIImageOrientation.RightMirrored:
                transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
                transform = CGAffineTransform.Rotate(transform, -(pi / 2));
                break;
        }

        switch (image.Orientation)
        {
            case UIImageOrientation.UpMirrored:
            case UIImageOrientation.DownMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                transform = CGAffineTransform.Scale(transform, -1, 1);
                break;

            case UIImageOrientation.LeftMirrored:
            case UIImageOrientation.RightMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
                transform = CGAffineTransform.Scale(transform, -1, 1);
                break;
        }

        var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent,
            image.CGImage.BytesPerRow, image.CGImage.ColorSpace, image.CGImage.BitmapInfo);

        ctx.ConcatCTM(transform);

        switch (image.Orientation)
        {
            case UIImageOrientation.Left:
            case UIImageOrientation.LeftMirrored:
            case UIImageOrientation.Right:
            case UIImageOrientation.RightMirrored:
                ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                break;

            default:
                ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                break;
        }

        var cgimg = ctx.ToImage();
        var img = new UIImage(cgimg);

        ctx.Dispose();
        ctx = null;
        cgimg.Dispose();
        cgimg = null;

        return img;
    }
Gustavo Baiocchi Costa
  • 1,379
  • 3
  • 16
  • 34