更新UIImage方向metaData?

基本任务:更新与UIImage关联的元数据的EXIF方向属性。 我的问题是,我不知道方向属性在所有EXIF信息中的位置。


Convoluted背景:我正在改变由imagePickerController:didFinishPickingMediaWithInfo:返回的图像的方向imagePickerController:didFinishPickingMediaWithInfo:所以我想我也需要更新writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata之前保存图像writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata

换句话说,除非我改变它,元数据将包含旧的/初始的方向,因此是错误的。 我改变方向的原因是因为当我运行Core Image脸检测程序时,它会让我绊倒。 使用前置摄像头在纵向模式下使用iPhone(设备)拍摄照片,方向为UIImageOrientationRight (3)。 如果我重写图像的方向是UIImageOrientationUp (0),我会得到很好的人脸检测结果。 作为参考,重写图像的例程如下。

整个相机方向的东西,我觉得很混乱,我似乎正在挖掘自己更深入到一个代码洞与所有这一切。 我看过post( 这里 , 这里和这里 。根据这个职位( https://stackoverflow.com/a/3781192/840992 ):

“相机实际上是风景本地的,所以当你拍摄照片的时候,当你拍摄照片时,你可以上下拍照,也可以在拍照时拍照(取决于你如何拿着照相机)。”

这是完全混淆的 如果以上是真的,我想我应该得到的UIImageOrientationLeftMirroredUIImageOrientationRightMirrored与前置摄像头的方向。 而这一切都不能解释为什么CIDetector失败的select器返回的处女形象。

我正在接近这个屁股倒退,但我似乎无法得到导向…


 -(UIImage *)normalizedImage:(UIImage *) thisImage { if (thisImage.imageOrientation == UIImageOrientationUp) return thisImage; UIGraphicsBeginImageContextWithOptions(thisImage.size, NO, thisImage.scale); [thisImage drawInRect:(CGRect){0, 0, thisImage.size}]; UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return normalizedImage; } 

看看我的答案在这里:
强制UIImagePickerController以纵向/维度iOS拍照

和github上的相关项目 (你不需要运行该项目,只需看看自述)。

它更关心的是阅读而不是写元数据 – 但是它包含了一些关于苹果的imageOrientation和相应的定位“Exif”元数据的笔记。

这也许值得一读
捕获的照片在iOS 6.0或iPhone上传期间自动旋转

播放中有两种不同的常量编号约定来指示图像的方向。

  1. 在TIFF / IPTC图像元数据标签中使用的kCGImagePropertyOrientation常量
  2. UIImage imageOrientation属性使用的UIImageOrientation常量。

iPhone本机摄像头方向是左侧风景(右侧是主屏幕button)。 原生像素尺寸总是反映这一点,旋转标志用于正确定位与显示方向的图像。

 Apple UIImage.imageOrientation TIFF/IPTC kCGImagePropertyOrientation iPhone native UIImageOrientationUp = 0 = Landscape left = 1 rotate 180deg UIImageOrientationDown = 1 = Landscape right = 3 rotate 90CCW UIImageOrientationLeft = 2 = Portrait down = 8 rotate 90CW UIImageOrientationRight = 3 = Portrait up = 6 

UIImageOrientation 4-7映射到kCGImagePropertyOrientation – 这些是镜像对应。

UIImage从底层kCGImagePropertyOrientation标志派生它的imagerOrientation属性 – 这就是为什么它是一个只读属性。 这意味着只要你得到正确的元数据标志,imageOrientation将正确地遵循。 但是,如果您正在阅读数字以应用转换,则需要注意您正在查看的数字。

从我的世界中收集到的一些细微之处在于:

背景: Core Image脸检测失败,它似乎与使用featuresInImage:options:和使用UIImage.imageOrientation属性作为参数有关。 如果图像被调整为不旋转而没有镜像,则检测工作正常,但直接从相机检测图像传递失败。

那么… UIImage.imageOrientation是不同于图像的实际方向。

换一种说法…

 UIImage* tmpImage = [self.imageInfo objectForKey:UIImagePickerControllerOriginalImage]; printf("tmpImage.imageOrientation: %d\n", tmpImage.imageOrientation); 

报告值为3或UIImageOrientationRight而使用由UIImagePickerControllerDelegate方法返回的元数据…

  NSMutableDictionary* metaData = [[tmpInfo objectForKey:@"UIImagePickerControllerMediaMetadata"] mutableCopy]; printf(" metaData orientation %d\n", [[metaData objectForKey:@"Orientation"] integerValue]); 

报告值为6或UIImageOrientationLeftMirrored

我想现在看来很明显, UIImage.imageOrientation是一个显示方向似乎由源图像方向设备旋转确定。 (我可能在这里是错误的)由于显示方向不同于实际的图像数据,使用它将导致CIDetector失败。 啊。

我相信所有这一切都为液体GUI等提供了非常好的和重要的目的,但是对于我来说太多了,因为所有的CIDetector坐标都会在原始的图像方向上使CALayer绘图生病。 所以,这里的后代是如何改变元数据的Orientation属性和其中包含的图像。 这个元数据然后可以用来保存图像到cameraRoll。

 // NORMALIZE IMAGE UIImage* tmpImage = [self normalizedImage:[self.imageInfo objectForKey:UIImagePickerControllerOriginalImage]]; NSMutableDictionary * tmpInfo =[self.imageInfo mutableCopy]; NSMutableDictionary* metaData = [[tmpInfo objectForKey:@"UIImagePickerControllerMediaMetadata"] mutableCopy]; [metaData setObject:[NSNumber numberWithInt:0] forKey:@"Orientation"]; [tmpInfo setObject:tmpImage forKey:@"UIImagePickerControllerOriginalImage"]; [tmpInfo setObject:metaData forKey:@"UIImagePickerControllerMediaMetadata"]; self.imageInfo = tmpInfo;