基本任务:更新与UIImage关联的metaData的EXIF定向属性。我的问题是,我不知道方向属性在所有EXIF信息中的位置。
复杂的背景:,我正在更改imagePickerController:didFinishPickingMediaWithInfo:返回的图像的方向,所以我认为在用writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata保存图像之前,还需要更新metaData。
换句话说,除非我更改它,否则metaData将包含旧的/初始的方向,因此是错误的。我之所以改变方向,是因为当我运行Core Image人脸检测例程时,它总是让我绊倒。使用前置相机与iPhone (设备)在肖像模式下拍照,方向为UIImageOrientationRight (3)。如果我重写图像,使方向是UIImageOrientationUp(0),我就能得到很好的人脸检测结果。作为参考,重写图像的例程如下所示。
整个相机定位的事情,我发现非常令人困惑,我似乎是挖掘自己更深的代码孔与所有这些。我看过这些帖子(这里,这里和这里 )。根据这篇文章(https://stackoverflow.com/a/3781192/840992):
“相机实际上是自然景物,所以当你在风景中拍摄一张照片时,你会上上下下,而当你在肖像中拍摄一张照片时,你会左右为难(这取决于你拿着设备的方式)。”
...which完全令人困惑。如果以上是真的,我会认为我应该得到一个UIImageOrientationLeftMirrored或UIImageOrientationRightMirrored的方向与前面的相机。所有这些都不能解释为什么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;
}发布于 2013-01-28 00:36:17
看看我的回答:
强迫UIImagePickerController在纵向方向/尺寸iOS中拍照
关于github的相关项目 (您不需要运行该项目,只需查看自述)。
它更关心的是阅读而不是写元数据--但它包含了苹果imageOrientation上的一些注释以及相应的方向“Exif”元数据。
这可能也值得一读。
有两个不同的常量编号惯例在发挥,以指示图像的方向。
iPhones本机相机的方向是左边的景物(右边是主页按钮)。本机像素尺寸总是反映这一点,旋转标志是用来正确定位图像与显示方向。
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 2,4,5,7 -这些是镜像对应的.
UIImage从底层的kCGImagePropertyOrientation标志派生出它的imagerOrientation属性--这就是为什么它是只读属性的原因。这意味着,只要正确使用元数据标志,imageOrientation就会正确运行。但是,如果为了应用转换而读取数字,则需要知道所查看的是哪些数字。
发布于 2013-01-28 02:24:29
在调查这件事时,我从我的世界中吸取了一些教训:
背景: Core Image人脸检测失败,这似乎与使用featuresInImage:选项:和使用UIImage.imageOrientation属性作为参数有关。当图像调整为没有旋转且没有镜像时,检测工作正常,但是当直接从摄像机传入图像时,检测失败。
嗯.UIImage.imageOrientation和图像的实际方向不同。
换句话说..。
UIImage* tmpImage = [self.imageInfo objectForKey:UIImagePickerControllerOriginalImage];
printf("tmpImage.imageOrientation: %d\n", tmpImage.imageOrientation);报告值为3或UIImageOrientationRight,而使用UIImagePickerControllerDelegate方法返回的metaData .
NSMutableDictionary* metaData = [[tmpInfo objectForKey:@"UIImagePickerControllerMediaMetadata"] mutableCopy];
printf(" metaData orientation %d\n", [[metaData objectForKey:@"Orientation"] integerValue]);报告值为6或UIImageOrientationLeftMirrored。
我想现在看来很明显,UIImage.imageOrientation是一个显示方向,它似乎由源图像方向和设备旋转决定。(这里我可能错了),因为显示方向与实际图像数据的方向不同,使用它会导致CIDetector失败。呃。
我确信所有这些对于液体图形信息系统来说都是非常好和重要的目的,但是对我来说这是太多了,因为所有的CIDetector坐标都将在原始的图像方向上,使CALayer绘图变得病态。因此,对于后人,这里是如何更改Orientation属性的metaData和其中包含的图像。然后可以使用这个metaData将图像保存到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;https://stackoverflow.com/questions/14553866
复制相似问题