UIImagePickerController returns incorrect image orientation

I use UIImagePickerController to capture an image and then save it. However, when I try to rescale it, the orientation value that I selected from this image is incorrect. When I click, holding the phone up, it gives me the orientation on the left. Has anyone experienced this problem?

The UIImagePickerController dictionary contains the following information:

{ UIImagePickerControllerMediaMetadata = { DPIHeight = 72; DPIWidth = 72; Orientation = 3; "{Exif}" = { ApertureValue = "2.970853654340484"; ColorSpace = 1; DateTimeDigitized = "2011:02:14 10:26:17"; DateTimeOriginal = "2011:02:14 10:26:17"; ExposureMode = 0; ExposureProgram = 2; ExposureTime = "0.06666666666666667"; FNumber = "2.8"; Flash = 32; FocalLength = "3.85"; ISOSpeedRatings = ( 125 ); MeteringMode = 1; PixelXDimension = 2048; PixelYDimension = 1536; SceneType = 1; SensingMethod = 2; Sharpness = 1; ShutterSpeedValue = "3.910431673351467"; SubjectArea = ( 1023, 767, 614, 614 ); WhiteBalance = 0; }; "{TIFF}" = { DateTime = "2011:02:14 10:26:17"; Make = Apple; Model = "iPhone 3GS"; Software = "4.2.1"; XResolution = 72; YResolution = 72; }; }; UIImagePickerControllerMediaType = "public.image"; UIImagePickerControllerOriginalImage = "<UIImage: 0x40efb50>"; } 

However, the image returns imageOrientation == 1 ;

 UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage]; 
+10
uiimage uiimagepickercontroller orientation scale
Feb 14 '11 at 5:25
source share
5 answers

I just started working on this issue in my own application.

I used the UIImage category that Trevor Harmon created to resize the image and fix its orientation, UIImage + Resize .

Then you can do something like this in -imagePickerController:didFinishPickingMediaWithInfo:

 UIImage * pickedImage = [info objectForKey: UIImagePickerControllerEditedImage];
 UIImage * resized = [pickedImage resizedImageWithContentMode: UIViewContentModeScaleAspectFit bounds: pickedImage.size interpolationQuality: kCGInterpolationHigh];

This fixed the problem for me. The modified image is oriented correctly visually, and the imageOrientation property reports UIImageOrientationUp.

There are several versions of this scale / size / crop code; I used Trevor because it looks pretty clean and includes some other UIImage manipulators that I want to use later.

+14
Feb 18 2018-11-21T00:
source share

This is what I found to fix the orientation problem; Works for me

 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; 
+8
Mar 09 '13 at 10:23
source share

Here is a Swift snippet that effectively fixes the problem:

 let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)! 
+4
Oct. 31 '14 at 2:04
source share

I use the following code, which I placed in a separate image utility object file, which has a bunch of other editing methods for UIImages:

 + (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSizeWithSameAspectRatio:(CGSize)targetSize { CGSize imageSize = sourceImage.size; CGFloat width = imageSize.width; CGFloat height = imageSize.height; CGFloat targetWidth = targetSize.width; CGFloat targetHeight = targetSize.height; CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0,0.0); if (CGSizeEqualToSize(imageSize, targetSize) == NO) { CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; if (widthFactor > heightFactor) { scaleFactor = widthFactor; // scale to fit height } else { scaleFactor = heightFactor; // scale to fit width } scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the image if (widthFactor > heightFactor) { thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; } else if (widthFactor < heightFactor) { thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } CGImageRef imageRef = [sourceImage CGImage]; CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); if (bitmapInfo == kCGImageAlphaNone) { bitmapInfo = kCGImageAlphaNoneSkipLast; } CGContextRef bitmap; if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) { bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); } else { bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); } // In the right or left cases, we need to switch scaledWidth and scaledHeight, // and also the thumbnail point if (sourceImage.imageOrientation == UIImageOrientationLeft) { thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x); CGFloat oldScaledWidth = scaledWidth; scaledWidth = scaledHeight; scaledHeight = oldScaledWidth; CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees CGContextTranslateCTM (bitmap, 0, -targetHeight); } else if (sourceImage.imageOrientation == UIImageOrientationRight) { thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x); CGFloat oldScaledWidth = scaledWidth; scaledWidth = scaledHeight; scaledHeight = oldScaledWidth; CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees CGContextTranslateCTM (bitmap, -targetWidth, 0); } else if (sourceImage.imageOrientation == UIImageOrientationUp) { // NOTHING } else if (sourceImage.imageOrientation == UIImageOrientationDown) { CGContextTranslateCTM (bitmap, targetWidth, targetHeight); CGContextRotateCTM (bitmap, -M_PI); // - 180 degrees } CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef); CGImageRef ref = CGBitmapContextCreateImage(bitmap); UIImage* newImage = [UIImage imageWithCGImage:ref]; CGContextRelease(bitmap); CGImageRelease(ref); return newImage; } 

And then I call

 UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage]; UIImage *fixedOriginal = [ImageUtil imageWithImage:[mediaInfoDict objectForKey:UIImagePickerControllerOriginalImage] scaledToSizeWithSameAspectRatio:pickedImage.size]; 
0
May 03 '13 at 12:55
source share

In iOS 7, I need code that depends on UIImage.imageOrientation to correct for different orientations. Now, in iOS 8.2, when I select my old test images from the album via the UIImagePickerController, the orientation will be UIImageOrientationUp for ALL images. When I take a photo (UIImagePickerControllerSourceTypeCamera), these images will also always be up, regardless of the orientation of the device. So, between these versions of iOS, obviously, there was a fix in which the UIImagePickerController already rotates images, if necessary. You may even notice that when displaying images of an album: for a second of a second they will be displayed in their original orientation before they appear in a new upward orientation.

0
Apr 3 '15 at 18:23
source share



All Articles