更新UIImage方向元数据?

No *_*ing 12 nsdictionary ios

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


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

换句话说,除非我更改它,否则metaData将包含旧/初始方向,因此是错误的.我改变方向的原因是因为它在我运行Core Image面部检测程序时不停地绊倒我.使用前置摄像头在人像模式下使用iPhone(设备)拍照时,方向为UIImageOrientationRight(3).如果我重写图像使方向为UIImageOrientationUp(0),我会得到良好的面部检测结果.作为参考,下面是重写图像的例程.

整个相机定位的事情我觉得非常混乱,我似乎正在深入挖掘所有这一切的代码洞.我看了帖子(这里,这里这里.根据这篇文章(/sf/answers/264683471/):

"相机实际上是风景原生的,所以当你拍摄风景照片时,你可以向上或向下拍摄,当你拍摄照片时,你可以向左或向右拍摄(取决于你握住设备的方式)."

......这完全令人困惑.如果以上情况属实,我认为我应该使用前置摄像头UIImageOrientationLeftMirroredUIImageOrientationRightMirrored使用前置摄像头.而这一切都无法解释为什么CIDetector选择器返回的原始图像失败了.

我正在接近这个屁股,但我似乎无法面向...


-(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;
}
Run Code Online (Sandbox Code Playgroud)

fou*_*dry 23

看看我的答案:
强制UIImagePickerController以纵向/尺寸iOS拍照

github上的相关项目(你不需要运行项目,只需看看自述文件).

它更关注阅读而不是编写元数据 - 但它包含了一些关于Apple的imageOrientation和相应的方向'Exif'元数据的注释.

这可能值得一读也
可以在IOS 6.0或iPhone上传时自动旋转捕获的照片

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

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

iPhone原生相机方向为左侧风景(右侧有主页按钮).原始像素尺寸始终反映这一点,旋转标记用于使显示方向正确定向图像.

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  
Run Code Online (Sandbox Code Playgroud)

UIImageOrientation4-7映射到kCGImagePropertyOrientation2,4,5,7 - 这些是镜像对应物.

UIImage从底层的kCGImagePropertyOrientation标志派生它的imagerOrientation属性 - 这就是它是一个只读属性的原因.这意味着只要您获得正确的元数据标记,imageOrientation就会正确跟随.但是,如果您要读取数字以应用变换,则需要知道您正在查看哪些数字.


No *_*ing 5

来自我的世界的一些收集者在研究这个问题时很痛苦:

背景: Core Image面部检测失败,似乎与使用featuresInImage:options:并使用UIImage.imageOrientation属性作为参数有关.将图像调整为无旋转且未镜像,检测工作正常,但直接从相机检测传入图像时检测失败.

嗯... UIImage.imageOrientation不同比图像的实际方向.

换一种说法...

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

报告值为3或者UIImageOrientationRight使用UIImagePickerControllerDelegate方法返回的metaData ...

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

报告值为6或UIImageOrientationLeftMirrored.

我认为现在看来显而易见的UIImage.imageOrientation显示方向,它看起来是由源图像方向设备旋转决定的.(I可能是错在这里)由于显示取向是不同的比实际的图像数据,使用将导致CIDetector失败.啊.

我确信所有这些对于液体图形用户界面等都是非常好的和重要的目的.但是对我来说它太多了,因为所有的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;
Run Code Online (Sandbox Code Playgroud)