Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIImagePickerController camera view rotating strangely on iOS 8 (pictures)

I have a very simple application: - All orientations are permitted with only a button on a screen - The button show a UIImagePickerController (to take a photo) - Build with Xcode 5 and SDK 7

On iOS 8, the camera of the UIImagePickerController is appearing correctly whether I am in landscape or in portrait, but when I rotate the device, I got the camera view rotated by 90 degrees, here's a an example:

  1. I have my app in portrait
  2. I push the button that shows me the UIImagePickerController
  3. I am in the camera view and I go to landscape mode, here is what I get:

The view is in landscape but the camera is rotated by 90 degrees

Did someone else already got this issue?

PS: And if I take a photo (again in landscape), the photo is correctly taken and now correctly displayed :


EDIT

The bug seems to be fixed on my iPad running iOS 8.1 but nothing appears related to that bug in iOS 8.1 Release Notes: https://developer.apple.com/library/content/releasenotes/General/RN-iOSSDK-8.1/

Thanks all for the proposed fixes for earlier versions of iOS 8!

like image 365
Kevin Hirsch Avatar asked Sep 19 '14 11:09

Kevin Hirsch


People also ask

Why does my iPhone keep turning my pictures sideways?

Swipe down from the top-right corner of your screen to open Control Center. Tap the Portrait Orientation Lock button to make sure that it's off.

Why is my camera showing sideways?

The reason your photo would appear this way is because the photo was taken that way (either with the phone sideways or upside down) and the image file itself is in this orientation. For example, if you hold your phone upright and take a photo, the photo is saved in portrait mode or "sideways".


2 Answers

I believe it is an iOS 8 bug. For example if you open your contacts app and click edit/add photo/take photo, the same issue occurs on a standard iOS app! Post the issue to Apple support just as I have.

like image 144
hitme Avatar answered Sep 18 '22 16:09

hitme


I have found an another very good solution for this issue which i am using currently. You just need to pass the image as an arugument to this method after capturing image using UIImagePickerController. It works well for all version of iOS and also for both portrait and landscape orientations of Camera. It checks for EXIF property of image using UIImageOrientaiton and accordind to the value of orientation, it transforms & scales the image so you will get the same return image with same orientation as your camera view orientation.

Here i have kept maximum resolutions of 3000 so that the image quality doesn't get spoiled specially while you are using retina devices but you can change its resolution as per your requirement.

// Objective C code:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info; {      UIImage *imagePicked = [info valueForKey:UIImagePickerControllerOriginalImage];       imagePicked = [self scaleAndRotateImage:imagePicked];       [[self delegate] sendImage:imagePicked];      [self.imagePicker dismissViewControllerAnimated:YES completion:nil];     }  - (UIImage *) scaleAndRotateImage: (UIImage *)image {     int kMaxResolution = 3000; // Or whatever      CGImageRef imgRef = image.CGImage;      CGFloat width = CGImageGetWidth(imgRef);     CGFloat height = CGImageGetHeight(imgRef);      CGAffineTransform transform = CGAffineTransformIdentity;     CGRect bounds = CGRectMake(0, 0, width, height);     if (width > kMaxResolution || height > kMaxResolution) {         CGFloat ratio = width/height;         if (ratio > 1) {             bounds.size.width = kMaxResolution;             bounds.size.height = bounds.size.width / ratio;         }         else {             bounds.size.height = kMaxResolution;             bounds.size.width = bounds.size.height * ratio;         }     }      CGFloat scaleRatio = bounds.size.width / width;     CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef),      CGImageGetHeight(imgRef));     CGFloat boundHeight;     UIImageOrientation orient = image.imageOrientation;     switch(orient)     {         case UIImageOrientationUp: //EXIF = 1              transform = CGAffineTransformIdentity;              break;          case UIImageOrientationUpMirrored: //EXIF = 2              transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);              transform = CGAffineTransformScale(transform, -1.0, 1.0);              break;          case UIImageOrientationDown: //EXIF = 3              transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);              transform = CGAffineTransformRotate(transform, M_PI);              break;          case UIImageOrientationDownMirrored: //EXIF = 4              transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);              transform = CGAffineTransformScale(transform, 1.0, -1.0);              break;          case UIImageOrientationLeftMirrored: //EXIF = 5              boundHeight = bounds.size.height;              bounds.size.height = bounds.size.width;              bounds.size.width = boundHeight;              transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);              transform = CGAffineTransformScale(transform, -1.0, 1.0);              transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);              break;          case UIImageOrientationLeft: //EXIF = 6              boundHeight = bounds.size.height;              bounds.size.height = bounds.size.width;              bounds.size.width = boundHeight;              transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);              transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);              break;          case UIImageOrientationRightMirrored: //EXIF = 7              boundHeight = bounds.size.height;              bounds.size.height = bounds.size.width;              bounds.size.width = boundHeight;              transform = CGAffineTransformMakeScale(-1.0, 1.0);              transform = CGAffineTransformRotate(transform, M_PI / 2.0);              break;          case UIImageOrientationRight: //EXIF = 8              boundHeight = bounds.size.height;              bounds.size.height = bounds.size.width;              bounds.size.width = boundHeight;              transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);             transform = CGAffineTransformRotate(transform, M_PI / 2.0);             break;          default:             [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];      }       UIGraphicsBeginImageContext(bounds.size);       CGContextRef context = UIGraphicsGetCurrentContext();       if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)      {          CGContextScaleCTM(context, -scaleRatio, scaleRatio);          CGContextTranslateCTM(context, -height, 0);      }      else {          CGContextScaleCTM(context, scaleRatio, -scaleRatio);          CGContextTranslateCTM(context, 0, -height);      }       CGContextConcatCTM(context, transform);       CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);      UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();      UIGraphicsEndImageContext();       return imageCopy; } 

// Swift 4.0 Code:

func scaleAndRotateImage(image: UIImage, MaxResolution iIntMaxResolution: Int) -> UIImage {         let kMaxResolution = iIntMaxResolution         let imgRef = image.cgImage!         let width: CGFloat = CGFloat(imgRef.width)         let height: CGFloat = CGFloat(imgRef.height)         var transform = CGAffineTransform.identity         var bounds = CGRect.init(x: 0, y: 0, width: width, height: height)          if Int(width) > kMaxResolution || Int(height) > kMaxResolution {             let ratio: CGFloat = width / height             if ratio > 1 {                 bounds.size.width = CGFloat(kMaxResolution)                 bounds.size.height = bounds.size.width / ratio             }             else {                 bounds.size.height = CGFloat(kMaxResolution)                 bounds.size.width = bounds.size.height * ratio             }         }         let scaleRatio: CGFloat = bounds.size.width / width         let imageSize = CGSize.init(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))          var boundHeight: CGFloat         let orient = image.imageOrientation         // The output below is limited by 1 KB.         // Please Sign Up (Free!) to remove this limitation.          switch orient {         case .up:             //EXIF = 1             transform = CGAffineTransform.identity         case .upMirrored:             //EXIF = 2             transform = CGAffineTransform.init(translationX: imageSize.width, y: 0.0)             transform = transform.scaledBy(x: -1.0, y: 1.0)          case .down:             //EXIF = 3             transform = CGAffineTransform.init(translationX: imageSize.width, y: imageSize.height)             transform = transform.rotated(by: CGFloat(Double.pi / 2))          case .downMirrored:             //EXIF = 4             transform = CGAffineTransform.init(translationX: 0.0, y: imageSize.height)             transform = transform.scaledBy(x: 1.0, y: -1.0)         case .leftMirrored:             //EXIF = 5             boundHeight = bounds.size.height             bounds.size.height = bounds.size.width             bounds.size.width = boundHeight             transform = CGAffineTransform.init(translationX: imageSize.height, y: imageSize.width)              transform = transform.scaledBy(x: -1.0, y: 1.0)             transform = transform.rotated(by: CGFloat(Double.pi / 2) / 2.0)             break          default: print("Error in processing image")         }          UIGraphicsBeginImageContext(bounds.size)         let context = UIGraphicsGetCurrentContext()         if orient == .right || orient == .left {             context?.scaleBy(x: -scaleRatio, y: scaleRatio)             context?.translateBy(x: -height, y: 0)         }         else {             context?.scaleBy(x: scaleRatio, y: -scaleRatio)             context?.translateBy(x: 0, y: -height)         }         context?.concatenate(transform)         context?.draw(imgRef, in: CGRect.init(x: 0, y: 0, width: width, height: height))         let imageCopy = UIGraphicsGetImageFromCurrentImageContext()         UIGraphicsEndImageContext()         return imageCopy!     } 
like image 33
sajgan2015 Avatar answered Sep 16 '22 16:09

sajgan2015