[英]iOS PNG Image rotated 90 degrees
在我写的iOS应用程序中,我处理PNG因为我处理alpha通道。 出于某种原因,我可以加载PNG到我imageView
就好了,但是当谈到时间中的图像复制了我的申请(到剪贴板)或图像保存到我的相机胶卷,图像旋转90度。
我在这里搜索了所有的东西,我学到的一件事是,如果我使用JPEG,由于EXIF信息,我不会有这个问题(听起来)。
我的应用程序具有完整的复制/粘贴功能,这里是踢球者(我会在步骤中编写它以便更容易理解):
我100%确定我的复制和粘贴代码没有错在这里,因为如果我回到上面的第2步,然后单击“保存”,照片将保存到我的库,但它旋转了90度!
更奇怪的是它似乎与从互联网上下载的图像一起工作正常,但是我手动用手机拍摄的图像非常受欢迎。 有些它有效,有些则不...
有没有人对此有任何想法? 我可以使用任何可能的工作吗? 我对代码非常有信心,因为它适用于大约75%的图像。 我可以根据要求发布代码。
对于那些需要Swift解决方案的人,创建UIImage的扩展并添加以下方法:
func correctlyOrientedImage() -> UIImage {
if self.imageOrientation == .up {
return self
}
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalizedImage ?? self;
}
如果由于现有的image imageOrientation
属性而遇到问题,则可以构建具有不同方向的其他相同图像,如下所示:
CGImageRef imageRef = [sourceImage CGImage];
UIImage *rotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];
您可能需要尝试在替换图像上设置的方向,可能会根据您开始的方向进行切换。
还要留意你的内存使用情况。 摄影应用程序经常耗尽,这将使每张照片的存储空间翻倍,直到您发布源图像。
花了几天时间,但我终于想通了@Dondragmer发布的答案。 但我想我会发布完整的解决方案。
所以基本上我必须编写一种方法来智能地自动旋转我的图像。 缺点是我必须在我的代码中随处调用这种方法,这是一种处理器密集型,特别是在移动设备上工作时,但优点是我可以拍摄图像,复制图像,粘贴图像,保存图像和它们都旋转得很好。 这是我最终使用的代码(该方法尚未100%完成,仍然需要编辑内存泄漏,什么不是)。
我最终了解到第一次将图像插入到我的应用程序中(无论是由于用户按下“拍摄图像”,“粘贴图像”或“选择图像”,由于某种原因它插入就好了没有自动在这一点上,我存储了一个名为imageOrientationWhenAddedToScreen
的全局变量中的旋转值。这使我的生活更轻松,因为当操作图像并将图像保存到程序之外时,我只是检查了这个缓存的全局变量并确定我是否需要正确旋转图像。
- (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%肯定为什么Apple有这种奇怪的图像旋转行为(试试这个......拿起你的手机并将其翻转并拍照,你会注意到最后的图片是正确的 - 也许这这就是为什么Apple有这种功能?)。
我知道我花了很多时间搞清楚这一点,所以我希望它能帮助其他人!
这种“奇怪的轮换”行为真的不是那么奇怪。 它很聪明,聪明的我指的是内存效率。 旋转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)
}
您可以使用Image 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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.