IOS: image rotates 90 degrees after saving as PNG view data

I researched enough to get this work, but could not fix it. After shooting from the camera, as long as I have an image stored as a UIImage, that’s fine, but as soon as I save this image as a PNG view, I can rotate it 90 degrees.

Below is my code and everything I tried:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType]; if([mediaType isEqualToString:(NSString*)kUTTypeImage]) { AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; delegate.originalPhoto = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; NSLog(@"Saving photo"); [self saveImage]; NSLog(@"Fixing orientation"); delegate.fixOrientationPhoto = [self fixOrientation:[UIImage imageWithContentsOfFile:[delegate filePath:imageName]]]; NSLog(@"Scaling photo"); delegate.scaledAndRotatedPhoto = [self scaleAndRotateImage:[UIImage imageWithContentsOfFile:[delegate filePath:imageName]]]; } [picker dismissModalViewControllerAnimated:YES]; [picker release]; } - (void)saveImage { AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; NSData *imageData = UIImagePNGRepresentation(delegate.originalPhoto); [imageData writeToFile:[delegate filePath:imageName] atomically:YES]; } 

Here are the fixOrientation and scaleAndRotateImage functions, taken from here and here respectively. They work fine and rotate the image when I apply them in UIImage, but they don't work if I save the image as a PNG representation and apply them.

Please refer to the following image after performing the following functions:

The first photo is original, second is saved, and third and fourth after applying fixorientation and scaleandrotate functions on saved image

+38
iphone uiimage image-rotation landscape-portrait
Jun 01 '12 at 12:23
source share
8 answers

Since iOS 4.0, when the camera takes a photo, it does not rotate it before saving, it

just sets the rotation flag in EXIF ​​JPEG data. If you save UIImage as JPEG, it

set the rotation flag. PNG does not support the rotation flag, so if you save the UIImage as

PNG, it will be rotated incorrectly and the flag will not be set to fix it. So if you want PNG

images, you must rotate them yourself, for this check the link .

+68
Jun 01 '12 at 12:35
source share

The version of the UIImage Swift 3.1 extension published by Rao:

 extension UIImage { func fixOrientation() -> UIImage { if self.imageOrientation == UIImageOrientation.up { return self } UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) if let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() { UIGraphicsEndImageContext() return normalizedImage } else { return self } } } 

Using:

 let cameraImage = //image captured from camera let orientationFixedImage = cameraImage.fixOrientation() 

Swift 4/5:

UIImageOrientation.up been renamed UIImage.Orientation.up

+27
Apr 03 '17 at 8:55
source share

Swift 4.2

Add the following as a UIImage extension,

 extension UIImage { func fixOrientation() -> UIImage? { if self.imageOrientation == UIImage.Orientation.up { return self } UIGraphicsBeginImageContext(self.size) self.draw(in: CGRect(origin: .zero, size: self.size)) let normalizedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return normalizedImage } } 

Usage example:

 let cameraImage = //image captured from camera let orientationFixedImage = cameraImage.fixOrientation() 
+19
Sep 20 '16 at 13:29
source share

I found the following helpful tips:

1. natural way out - landscape

2..width / .height ARE depends on .imageOrientation

3 use short size, not .width




(1) "natural" camera output for IS LANDSCAPE still images .

this is contradictory. portrait is the only way offered by UIImagePickerController, etc. But you will get the UIImageOrientationRight as the “normal” orientation when using the “normal” portrait camera

(The way I remember this is a natural conclusion for the video (of course) landscape, so the still images are the same - even if the iPhone is a portrait.)




(2) .width and .height are really affected by .imageOrientation !!!!!!!!!

Be sure to do this, and try both options on your iPhone,

 NSLog(@"fromImage.imageOrientation is %d", fromImage.imageOrientation); NSLog(@"fromImage.size.width %f fromImage.size.height %f", fromImage.size.width, fromImage.size.height); 

you will see that the .height and .width variables, even though real pixels are landscape.




(3) just using “short dimension” rather than width can often solve many problems

I found this incredibly useful. Let's say you want perhaps the top square of the image:

 CGRect topRectOfOriginal = CGRectMake(0,0, im.size.width,im.size.width); 

which doesn’t actually work, you get a squeaky image when the camera (“really”) is held in the landscape.

however, if you just do it

 float shortDimension = fminf(im.size.width, im.size.height); CGRect topRectOfOriginal = CGRectMake(0,0, shortDimension,shortDimension); 

then “everything fixed”, and you really “don't need to worry about” the orientation flag. Again, point (3) is not a cure, but very often solves all problems.

Hope this helps someone save some time.

+6
Mar 09 '14 at 13:48
source share

I found this code here , which actually fixed it for me. For my application, I took a picture and saved it, and every time I downloaded it, it would have an annoying rotation (I looked up, and this apparently has something to do with EXIF ​​and the way the iPhone takes and stores images). This code fixed it for me. I have to say that it was originally an addition to the class / extension / category (you can find the original by reference. I used it as below as a simple method, since I really did not want to make an entire class or category just for that. I used just a portrait, but I think the code works for any orientation. I'm not sure though

Repeat, here is the code:

 - (UIImage *)fixOrientationForImage:(UIImage*)neededImage { // No-op if the orientation is already correct if (neededImage.imageOrientation == UIImageOrientationUp) return neededImage; // 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 (neededImage.imageOrientation) { case UIImageOrientationDown: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, neededImage.size.width, neededImage.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, neededImage.size.width, 0); transform = CGAffineTransformRotate(transform, M_PI_2); break; case UIImageOrientationRight: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, 0, neededImage.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; case UIImageOrientationUp: case UIImageOrientationUpMirrored: break; } switch (neededImage.imageOrientation) { case UIImageOrientationUpMirrored: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, neededImage.size.width, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationLeftMirrored: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, neededImage.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, neededImage.size.width, neededImage.size.height, CGImageGetBitsPerComponent(neededImage.CGImage), 0, CGImageGetColorSpace(neededImage.CGImage), CGImageGetBitmapInfo(neededImage.CGImage)); CGContextConcatCTM(ctx, transform); switch (neededImage.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0,0,neededImage.size.height,neededImage.size.width), neededImage.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0,0,neededImage.size.width,neededImage.size.height), neededImage.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; } 

I'm not sure how useful this is for you, but I hope this helps :)

+3
Dec 08 '15 at 23:11
source share

Try it, you can use

 NSData *somenewImageData = UIImageJPEGRepresentation(newimg,1.0); 

instead

 NSData *somenewImageData = UIImagePNGRepresentation(newimg); 
+3
Jan 31 '17 at 5:39 on
source share

Pls try the following code

 UIImage *sourceImage = ... // Our image CGRect selectionRect = CGRectMake(100.0, 100.0, 300.0, 400.0); CGImageRef resultImageRef = CGImageCreateWithImageInRect(sourceImage.CGImage, selectionRect); UIImage *resultImage = [[UIImage alloc] initWithCGImage:resultImageRef]; 

AND

 CGRect TransformCGRectForUIImageOrientation(CGRect source, UIImageOrientation orientation, CGSize imageSize) { switch (orientation) { case UIImageOrientationLeft: { // EXIF #8 CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.height, 0.0); CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI_2); return CGRectApplyAffineTransform(source, txCompound); } case UIImageOrientationDown: { // EXIF #3 CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI); return CGRectApplyAffineTransform(source, txCompound); } case UIImageOrientationRight: { // EXIF #6 CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(0.0, imageSize.width); CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI + M_PI_2); return CGRectApplyAffineTransform(source, txCompound); } case UIImageOrientationUp: // EXIF #1 - do nothing default: // EXIF 2,4,5,7 - ignore return source; } } ... UIImage *sourceImage = ... // Our image CGRect selectionRect = CGRectMake(100.0, 100.0, 300.0, 400.0); CGRect transformedRect = TransformCGRectForUIImageOrientation(selectionRect, sourceImage.imageOrientation, sourceImage.size); CGImageRef resultImageRef = CGImageCreateWithImageInRect(sourceImage.CGImage, transformedRect); UIImage *resultImage = [[UIImage alloc] initWithCGImage:resultImageRef]; 

I link to the following link, looking for more detail

Regards: -)

+1
Jun 01 '12 at 12:40
source share

Try this code:

 NSData *imageData = UIImageJPEGRepresentation(delegate.originalPhoto,100); 
0
May 26 '15 at 12:35
source share



All Articles