IOS PNG Image rotated 90 degrees

In my iOS application, I write, I am dealing with PNG, because I am dealing with an alpha channel. For some reason, I can upload PNG to my imageView just fine, but when it comes time to either copy the image from my application (on the PasteBoard) or save the image in a camera roll, the image rotates 90 degrees.

I searched everywhere on this, and one of the things that I found out is that if I used JPEG I would not have this problem (it sounds) due to EXIF ​​information.

My application has full copy / paste functionality, and here is a kicker (I will write it step by step to make it easier to follow):

  • Go to the camera roll and copy the image.
  • Go into my application and click "Paste", the image is inserted in order, and I can do this all day.
  • Select the copy function that I performed, and then click "Paste", and the image is inserted, but rotated.

I am 100% sure that my code for copying and pasting is not what is wrong here, because if I go back to step 2 above and click save, the photo will be saved in my library, but it will be rotated 90 degrees!

What's even weirder is that it works great with images downloaded from the Internet, but it hit or missed the images that I manually took with the phone. Some of them work, some of them don’t ...

Does anyone have any thoughts on this? Any possible work I can use? I am pretty sure about the code because it works on about 75% of my images. I can send the code on request, though.

+26
ios objective-c iphone png exif
Apr 24 2018-12-12T00:
source share
6 answers

Took a few days, but I finally figured it out thanks to @Dondragmer's answer. But I decided that I would send my complete solution.

So basically I had to write a method to intellectually automatically rotate my images. The disadvantage is that I have to call this method throughout my code, and it is very intense, especially when working on mobile devices, but the plus side is that I can take pictures, copy images, paste images and save images and they all rotate properly. Here is the code I used (the method is not 100% complete, you still need to edit the memory leaks and what not).

As a result, I found out that for the first time the image was inserted into my application (whether it was due to the user clicking “take the image”, “insert the image” or “select the image”, for some reason it inserts only fine, without automatic At that moment I saved all rotation values ​​in a global variable called imageOrientationWhenAddedToScreen , which made my life easier because when it came time to manipulate the image and save the image from the program, I just checked this global cached variable and defined He asked if I need to rotate the image correctly.

  - (UIImage*) rotateImageAppropriately:(UIImage*) imageToRotate { //This method will properly rotate our image, we need to make sure that //We call this method everywhere pretty much... CGImageRef imageRef = [imageToRotate CGImage]; UIImage* properlyRotatedImage; if (imageOrientationWhenAddedToScreen == 0) { //Don't rotate the image properlyRotatedImage = imageToRotate; } else if (imageOrientationWhenAddedToScreen == 3) { //We need to rotate the image back to a 3 properlyRotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:3]; } else if (imageOrientationWhenAddedToScreen == 1) { //We need to rotate the image back to a 1 properlyRotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:1]; } return properlyRotatedImage; } 

I’m still not 100% sure why Apple has this strange behavior in handling pictures (try this ... Take your phone and turn it upside down and take a picture, you will notice that the final image is obtained from the right up - maybe , which is why Apple has such functionality?).

I know that I spent a lot of time on this, so I hope this helps other people!

+13
Apr 29 '12 at 3:13
source share

For those who want a Swift solution, create a UIImage extension and add the following method:

 func correctlyOrientedImage() -> UIImage { if self.imageOrientation == UIImageOrientation.Up { return self } UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height)) var normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return normalizedImage; } 
+23
Oct 27 '14 at 0:45
source share

If you are having problems due to the existing imageOrientation image, you can build another identical image with a different orientation, for example:

 CGImageRef imageRef = [sourceImage CGImage]; UIImage *rotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp]; 

You may need to experiment with which orientation to install on your removable images, perhaps switching based on the orientation you started with.

Also monitor your memory usage. Photography apps often end up, and it will be twice as much as your storage per image until you release the original image.

+14
Apr 25 2018-12-12T00:
source share

This behavior of "strange rotation" is really not so strange. This is reasonable, and by smart, I mean memory efficiency. When you turn an iOS device, the camera hardware rotates with it. When you take a picture, the image will be recorded, however, the camera is oriented. UIImage can use this raw image data without copying, simply by tracking the orientation in which it should be. When you use UIImagePNGRepresentation() , you lose this orientation data and get the PNG of the main image, as was done by the camera. To fix this instead of rotation, you can point to the original image to draw yourself to a new context and get a correctly oriented UIImage from that context.

 UIImage *image = ...; //Have the image draw itself in the correct orientation if necessary if(!(image.imageOrientation == UIImageOrientationUp || image.imageOrientation == UIImageOrientationUpMirrored)) { CGSize imgsize = image.size; UIGraphicsBeginImageContext(imgsize); [image drawInRect:CGRectMake(0.0, 0.0, imgsize.width, imgsize.height)]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } NSData *png = UIImagePNGRepresentation(image); 
+12
Feb 05 '14 at 19:35
source share

Here is another way to achieve this:

 @IBAction func rightRotateAction(sender: AnyObject) { let imgToRotate = CIImage(CGImage: sourceImageView.image?.CGImage) let transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2)) let rotatedImage = imgToRotate.imageByApplyingTransform(transform) let extent = rotatedImage.extent() let contex = CIContext(options: [kCIContextUseSoftwareRenderer: false]) let cgImage = contex.createCGImage(rotatedImage, fromRect: extent) adjustedImage = UIImage(CGImage: cgImage)! UIView.transitionWithView(sourceImageView, duration: 0.5, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: { self.sourceImageView.image = self.adjustedImage }, completion: nil) } 
0
Aug 13 '15 at 10:38
source share

You can use Image I / O to save the PNG image to a file (or NSMutableData ) relative to the orientation of the image. In the example below, I am saving a PNG image in a path file.

 - (BOOL)savePngFile:(UIImage *)image toPath:(NSString *)path { NSData *data = UIImagePNGRepresentation(image); int exifOrientation = [UIImage cc_iOSOrientationToExifOrientation:image.imageOrientation]; NSDictionary *metadata = @{(__bridge id)kCGImagePropertyOrientation:@(exifOrientation)}; NSURL *url = [NSURL fileURLWithPath:path]; CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); if (!source) { return NO; } CFStringRef UTI = CGImageSourceGetType(source); CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, UTI, 1, NULL); if (!destination) { CFRelease(source); return NO; } CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)metadata); BOOL success = CGImageDestinationFinalize(destination); CFRelease(destination); CFRelease(source); return success; } 

cc_iOSOrientationToExifOrientation: - method of the UIImage category.

 + (int)cc_iOSOrientationToExifOrientation:(UIImageOrientation)iOSOrientation { int exifOrientation = -1; switch (iOSOrientation) { case UIImageOrientationUp: exifOrientation = 1; break; case UIImageOrientationDown: exifOrientation = 3; break; case UIImageOrientationLeft: exifOrientation = 8; break; case UIImageOrientationRight: exifOrientation = 6; break; case UIImageOrientationUpMirrored: exifOrientation = 2; break; case UIImageOrientationDownMirrored: exifOrientation = 4; break; case UIImageOrientationLeftMirrored: exifOrientation = 5; break; case UIImageOrientationRightMirrored: exifOrientation = 7; break; default: exifOrientation = -1; } return exifOrientation; } 

You can also save the NSData image using CGImageDestinationCreateWithData and pass NSMutableData instead of NSURL to CGImageDestinationCreateWithURL .

0
May 17 '16 at 10:30
source share



All Articles