【问题标题】:AVCaptureMovieFileOutput causing wrong orientation when saving photo to Camera Roll将照片保存到相机胶卷时,AVCaptureMovieFileOutput 导致方向错误
【发布时间】:2011-06-15 00:12:06
【问题描述】:

我对 captureStillImageAsynchronouslyFromConnection 有一个奇怪的问题。如果我在镜像视频时使用 jpegStillImageNSDataRepresentation 保存图像,则相机胶卷中的图像会顺时针旋转 90 度。但是,如果没有镜像,则方向很好。 我会发布代码,其他人有这个问题/知道解决方法吗?

更新:刚刚进行了一些测试,高度和宽度 (640x480) 都很好,反映了设备的方向。当我在纵向拍照时,它会报告 UIImageOrientationLeft,当镜像时,它会报告 UIImageOrientationLeftMirrored。

更新 2:当我在相机胶卷中查看保存的照片时,图像的预览方向正确,在照片之间滑动时图像也是如此,但当照片完全加载时,它会旋转 90 度。这可能是相机胶卷问题吗? (我在 4.3.3)

- (void) captureImageAndSaveToCameraRoll
{
    AVCaptureConnection *stillImageConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]];
    if ([stillImageConnection isVideoOrientationSupported])
        [stillImageConnection setVideoOrientation:[self orientation]];

    [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:stillImageConnection
                                                         completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

                                                             ALAssetsLibraryWriteImageCompletionBlock completionBlock = ^(NSURL *assetURL, NSError *error) {
                                                                 if (error) {
                                                                     if ([[self delegate] respondsToSelector:@selector(captureManager:didFailWithError:)]) {
                                                                         [[self delegate] captureManager:self didFailWithError:error];
                                                                     }
                                                                 }
                                                             };

                                                             if (imageDataSampleBuffer != NULL) {
                                                                 NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                                                                 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

                                                                 UIImage *image = [[UIImage alloc] initWithData:imageData];
                                                                 [library writeImageToSavedPhotosAlbum:[image CGImage]
                                                                                           orientation:(ALAssetOrientation)[image imageOrientation]
                                                                                       completionBlock:completionBlock];
                                                                 [image release];

                                                                 [library release];
                                                             }
                                                             else
                                                                 completionBlock(nil, error);

                                                             if ([[self delegate] respondsToSelector:@selector(captureManagerStillImageCaptured:)]) {
                                                                 [[self delegate] captureManagerStillImageCaptured:self];
                                                             }
                                                         }];
}

【问题讨论】:

  • 要调试它,如果你在两种模式下输出 image.size 和 imageOrientation 可能会有所帮助,你会得到什么值?
  • 刚刚进行了一些测试,高度和宽度(640x480)都很好,反映了设备的方向。当我在纵向拍照时,它会报告 UIImageOrientationLeft,当镜像时,它会报告 UIImageOrientationLeftMirrored。

标签: iphone ios avfoundation avcapturesession avcam


【解决方案1】:

我想知道你新创建的图像是否真的像你在这里假设的那样设置了它的方向:

[library writeImageToSavedPhotosAlbum:[image CGImage] orientation: (ALAssetOrientation) [image imageOrientation] completionBlock:completionBlock];

[image imageOrientation] 似乎特别可能是问题的根源,尤其是在需要演员阵容的情况下......

你说你在某处看到图像方向,是不是来自[image imageOrientation] 刚刚创建它之后:

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation: imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];

我想知道您是否假设此元数据位于从 AVCaptureStillImageOutput jpegStillImageNSDataRepresentation: 返回的 imageData 中,而实际上它只包含图像像素数据本身?

【讨论】:

  • 注意 specifically documented 可以将 UIImageOrientation 转换为 ALAssetOrientation。
  • 啊,太好了!它是否获得了正确的价值?正如我上面所说,我想知道元数据是否进入imageData,然后被解析并添加到image。如果我理解您的问题,只是试图追踪数据从哪里开始并在系统中移动,因为它似乎没有到达它需要的地方。
【解决方案2】:

根据some reports 的说法,2009 年 iPhone 的照片应用程序根本不支持任何镜像方向;他们当然有可能部分修复了这个问题,但在某些情况下仍然存在错误(例如,我知道 UIImageView 在某些情况下不能正确处理contentStretch)。这应该很容易测试:只需将该博客中的示例图像加载到相机胶卷中,看看会发生什么。

【讨论】:

  • 我使用的代码是 AVCam 1.0 和 1.2 的混合加上我自己的代码。我想这就是您无法在 AVCam 1.2 中保存照片的原因?愚蠢的。为什么我必须将照片保存为镜像?我要做的就是保存镜像视频的照片。
  • 有没有一种简单的方法可以在保存到相机胶卷之前拍照并垂直翻转?
  • @WDyson:当然,请参阅stackoverflow.com/questions/5427656/… 了解之前的问题。
【解决方案3】:

iOS UIImagePickerController result image orientation after upload中描述的UIImage创建类别

在将图像保存到您的库之前调用此方法。

【讨论】:

  • 奇怪的事情。我的图像现在都旋转了 180 度,上下颠倒。
  • 你必须修改它来做你想做的事。虽然逻辑应该是类似的。
  • 我冒昧地编辑了您的答案,只是链接到我之前关于图像旋转的答案,而不是逐字复制。 -1 抄袭,以及只是从我在 14 小时前的评论中发布的链接中复制您的答案。
  • 我没有从您的答案中复制它,该代码遍布互联网。我已经在我的几个项目中使用了它。认为你的答案是我唯一可能遇到的地方有点自负,不是吗?
  • 哇,网上有人抄我的代码?漂亮。
猜你喜欢
  • 2014-09-04
  • 2012-07-22
  • 1970-01-01
  • 2013-04-03
  • 2013-07-18
  • 2012-05-01
  • 2013-06-27
  • 1970-01-01
  • 2018-09-22
相关资源
最近更新 更多