UIImagePNGR questions? / Images rotated 90 degrees

I want to upload images from UIImagePickerController, and then save the selected photo to the application’s document directory.

UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; NSData *data1 = UIImagePNGRepresentation(image); NSString *fileName = "1.png"; NSString *path = //get Document path, then add fileName BOOL succ = [data1 writeToFile:path atomically:YES]; 

but after I saved the image in my document, I found that the image was rotated 90 degrees, and then I changed the UIImagePNGR view method to the UIImageJPEGR view, this time it’s fine, does anyone know what the problem is?

+48
iphone cocoa-touch uiimagepngrepresentation
Aug 24 '10 at 7:20
source share
6 answers

I had the same problem, and I found out the reason: since iOS 4.0, when the camera takes a photo, it does not rotate it before saving, it just sets the rotation flag in JPEG EXIF ​​data.

If you save the UIImage as a JPEG, it will set the rotation flag.

PNG does not support the rotation flag, so if you save the UIImage as a PNG, it will be rotated incorrectly and the flag will not be set to fix it. Therefore, if you want to use PNG, you must rotate them yourself.

I would call this a bug in the PNG save function, but it's just an opinion (they should at least warn you about this).

+87
Feb 01 2018-11-11T00:
source share

Please try this.

 func rotateImage(image: UIImage) -> UIImage? { if (image.imageOrientation == UIImage.Orientation.up ) { return image } UIGraphicsBeginImageContext(image.size) image.draw(in: CGRect(origin: CGPoint.zero, size: image.size)) let copy = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return copy } 

Have a nice coding :)

+21
Oct 23 '15 at 9:52
source share

I solve this problem with the following code.

 - (UIImage *)scaleAndRotateImage:(UIImage *)image { int kMaxResolution = 640; 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; } 
+14
Dec 16 '13 at 13:15
source share

The following swift function solves the problem.

 func rotateImage(image: UIImage) -> UIImage? { if (image.imageOrientation == UIImage.Orientation.up ) { return image } UIGraphicsBeginImageContext(image.size) image.draw(in: CGRect(origin: CGPoint.zero, size: image.size)) let copy = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return copy } 

Yes, it's that simple, because the drawInRect function will take into account the orientation of the image.

+3
Sep 07 '15 at 10:18
source share

I created this UIImage extension to fix this problem using the UIImagePNGRe view based on this answer . Therefore, I suggest using this func UIImage.PNGRepresentation(img: UIImage) class instead of the UIKit func UIImagePNGRview.

Swift 3 Code:

 // MyUIImage.swift // MyEasyMovie-Public-App // // Created by Ahmed Zahraz on 19/12/2016. // Copyright © 2016 AhmedZahraz. All rights reserved. import Foundation import UIKit extension UIImage { public class func PNGRepresentation(_ img: UIImage) -> Data? { // No-op if the orientation is already correct if (img.imageOrientation == UIImageOrientation.up) { return UIImagePNGRepresentation(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 UIImagePNGRepresentation(imgEnd) } } 
+2
Dec 20 '16 at 16:33
source share

Stefan's answer updated for Swift 4:

 func rotateImage(image: UIImage) -> UIImage { if (image.imageOrientation == UIImage.Orientation.up) { return image } UIGraphicsBeginImageContext(image.size) image.draw(in: CGRect(origin: .zero, size: image.size)) let copy = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return copy! } 

And then:

 var originalImage = yourImage.image! image = rotateImage(image: originalImage) 
+1
Oct 21 '18 at 18:11
source share



All Articles