Camera image orientation
Solution 1
you should fix orientation of image captured by camera the code follows, by default the orientation of camera image is not correct
- (UIImage *)fixrotation:(UIImage *)image
{
if (image.imageOrientation == UIImageOrientationUp) return image;
CGAffineTransform transform = CGAffineTransformIdentity;
switch (image.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, image.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (image.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, image.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, image.size.width, image.size.height,
CGImageGetBitsPerComponent(image.CGImage), 0,
CGImageGetColorSpace(image.CGImage),
CGImageGetBitmapInfo(image.CGImage));
CGContextConcatCTM(ctx, transform);
switch (image.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.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;
}
Solution 2
-[UIImage imageOrientation] might help :)
Image orientation affects the way the image data is displayed when drawn. By default, images are displayed in the “up” orientation. If the image has associated metadata (such as EXIF information), however, this property contains the orientation indicated by that metadata. For a list of possible values for this property, see “UIImageOrientation.”
Since that property is readonly, and depending on what you want to do, a possible (but ugly) solution could be:
UIImage *sourceImage = [arrayImage objectAtIndex:0];
NSData *data = UIImagePNGRepresentation(sourceImage);
UIImage *tmp = [UIImage imageWithData:data];
UIImage *fixed = [UIImage imageWithCGImage:tmp.CGImage
scale:sourceImage.scale
orientation:sourceImage.imageOrientation];
(untested and there might/must be something cleaner)
EDIT : First part was an answer to your question, an explanation more than a fix.
This and this (old?) blog posts might be interesting readings for you. Strangely I've never met this issue while I'm using UIImageJPEGRepresentation
to send images to a server... What iOS version are you working on? That could be an old SDK bug?
Solution 3
I think this is a bug with the SDK. I ran into this exact problem and then switched over to UIImageJPEGRepresentation which fixed the problem.
Solution 4
//iOS Swift 3
func fixRotation(image: UIImage) -> UIImage
{
if (image.imageOrientation == .up)
{
return image
}
var transform: CGAffineTransform = .identity
switch image.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: image.size.height)
transform = transform.rotated(by: .pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.rotated(by: .pi / 2)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: image.size.height)
transform = transform.rotated(by: -(.pi / 2))
case .up, .upMirrored:
break
}
switch image.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: image.size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let cgimage = image.cgImage
let bitsPerComponent = cgimage?.bitsPerComponent
let colorSpace = cgimage?.colorSpace
let bitmapInfo = cgimage?.bitmapInfo
let ctx = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: bitsPerComponent! , bytesPerRow: 0, space: colorSpace!, bitmapInfo: bitmapInfo!.rawValue)
ctx?.concatenate(transform)
switch image.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
// Grr...
ctx?.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
default:
ctx?.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
}
let cgimg: CGImage = ctx!.makeImage()!
let img = UIImage(cgImage: cgimg)
return img
}
DNewell
Updated on June 05, 2022Comments
-
DNewell almost 2 years
In my app I'm capturing images using the Camera. These are being stored in an NSArray as an NSData representation. When I convert the NSData back to the image, the orientation is now landscape instead of portrait as I took it.
NSData *data = UIImagePNGRepresentation([arrayImage objectAtIndex:0]); UIImage *tmp = [UIImage imageWithData:data];
Anyone have an explanation? Thanks.
-
DNewell about 13 yearsWell that did solve the problem inside the app. However, it doesn't matter which way I orient the image in the app, when I convert back to NSData for sending the image in an email, the image goes back to the 90 degrees CCW from the original. This certainly seems like a bug?
-
Vincent Guerci about 13 yearsedited answer with interesting links, next time please post a more detailed question.
-
Boeckm about 12 yearsAny confirmation on this? I'm having the same problem and can't find a fix for the life of me. Using JPEG representation is out of the question for me as I need the alpha channel PNGs offer.
-
A-Live about 11 yearsThe orientation is correct. Incorrect is the logic of some developers who do not respect metadata when transferring or displaying the image.
-
William T. over 8 yearsThis helped me. I have confirmed that the image orientation issue doesn't happen with JPEG conversion