iOS PNG图像旋转了90度

在我写的iOS应用程序中,我处理的是PNG,因为我处理Alpha通道。 出于某种原因,我可以将PNG加载到我的imageView中,但是当它将图像从我的应用程序中复制(粘贴到PasteBoard上)或将图像保存到相机胶卷上时,图像旋转90度。

我在这里到处search,我学到的东西之一是,如果我使用JPEG,我不会有这个问题(听起来),由于EXIF的信息。

我的应用程序具有完整的复制/粘贴function,这里是踢球者(我会逐步写下来,以便更容易遵循):

  1. 去我的相机胶卷,复制一个图像
  2. 进入我的应用程序,然后按“粘贴”,图像粘贴就好了,我可以整天这样做
  3. 点击我实现的复制function,然后点击“粘贴”,图像粘贴但旋转。

我100%确定我的复制和粘贴代码是不是这里有什么错,因为如果我回到上面的第2步,并点击“保存”,照片保存到我的图书馆,但它是旋转90度!

更奇怪的是,从网上下载的图片似乎可以正常工作,但是用手动手动拍摄的图片非常受欢迎。 有些是有效的,有些则不是。

有没有人有这个想法? 任何可能的解决办法,我可以使用? 我对代码的相当有信心,它对我的​​图像有75%的作用。 我可以根据要求发布代码。

对于那些想要一个Swift解决scheme,创build一个UIImage的扩展,并添加以下方法:

 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; } 

如果由于现有图像imageOrientation属性而遇到麻烦,则可以使用不同的方向构造一个完全相同的图像,如下所示:

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

您可能需要尝试在replace图像上设置什么方向,可能会根据开始的方向进行切换。

还要留意你的内存使用情况。 摄影应用程序经常用完,这将使您的每个图片的存储空间增加一倍,直到您释放源图像。

花了几天,但我终于find了答案@Dondragmer张贴。 但我想我会发布我的完整解决scheme。

所以基本上我不得不写一个方法来智能地自动旋转我的图像。 缺点是我必须在我的代码中随处调用这个方法,这是一种处理器密集型的方式,特别是在移动设备上工作的时候,但另一方面,我可以拍摄图像,复制图像,粘贴图像以及保存图像他们都旋转正常。 这是我最终使用的代码(该方法不是100%完成,仍然需要编辑内存泄漏,什么不是)。

我最终了解到,第一次插入到我的应用程序的图像(无论是由于用户按“拍摄图像”,“粘贴图像”或“select图像”,由于某些原因,它插入就没有自动罚款旋转,此时,我将所有的旋转值存储在一个名为imageOrientationWhenAddedToScreen的全局variables中,这让我的生活变得更加简单,因为当操作图像并将图像保存在程序之外时,我简单地检查了这个caching的全局variables并确定是否需要正确旋转图像。

  - (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; } 

我仍然不是100%确定为什么苹果有这种奇怪的图像旋转行为(试试这个…把你的手机,把它颠倒,拍照,你会发现最终的图片变成正确的一面 – 也许这为什么苹果有这种function?)。

我知道我花了很多时间来解决这个问题,所以我希望它能帮助别人!

这种“奇怪的旋转”行为实际上并不奇怪。 这是聪明的,聪明的我的意思是记忆效率。 当您旋转iOS设备时,相机硬件随之旋转。 当您拍摄照片时,将拍摄照片,但相机朝向。 UIImage能够使用这个原始图片数据,而不需要复制,只需要跟踪它应该在的方向。当你使用UIImagePNGRepresentation()你失去了这个方向数据,并得到一个PNG的底层图像,因为它是由相机。 为了解决这个问题,而不是旋转,你可以告诉原始图像绘制自己到一个新的上下文,并从该上下文中获取正确的UIImage

 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); 

这是实现这一目标的另一种方法:

 @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) } 

您可以使用图像I / O将PNG图像保存为文件(或NSMutableData )与图像的方向有关。 在下面的示例中,我将PNG图像保存到path的文件。

 - (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:UIImage类的一个方法。

 + (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; } 

您也可以使用CGImageDestinationCreateWithData将图像保存到NSData并在CGImageDestinationCreateWithURL传递NSMutableData而不是NSURL