【问题标题】:Force UIImagePickerController to take photo in portrait orientation/dimensions iOS强制 UIImagePickerController 以纵向/尺寸 iOS 拍照
【发布时间】:2013-01-07 05:36:09
【问题描述】:

我的应用中唯一允许的方向是横向。我在目标>summery下的项目属性中强制执行此操作,并且只允许shouldAutorotateToInterfaceOrientation中的肖像

问题是当我水平握住手机(横向)拍照时,照片将以横向拍摄,而 UI 仍然是纵向模式。

这意味着在横向模式下,我获得了 3264 x 2448 的宽图像,而不是纵向模式下获得的高大图像 (2448 x 3264)。

接下来用户可以裁剪图像,但如果图像是在横向模式下拍摄的,我会得到非常难看的拉伸图像。添加边框或将 UI 切换为横向不是一种选择。

有没有办法强制UIImagePickerController 拍摄纵向尺寸的照片,即使手机水平握持(横向模式)?

我使用以下设置初始化UIImagePickerController

    imagePicker =[[UIImagePickerController alloc] init];
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
    imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
    imagePicker.showsCameraControls = NO;
    imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
    imagePicker.wantsFullScreenLayout = YES;
    imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform,CAMERA_TRANSFORM, CAMERA_TRANSFORM);
    imagePicker.navigationBarHidden = YES;
    imagePicker.toolbarHidden = YES;
    [self presentModalViewController:imagePicker animated:NO];
    imagePicker.cameraOverlayView = self.cameraOverlay;
    imagePicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;

【问题讨论】:

  • 嗨!我也有同样的问题。答案中提供的哪些选项解决了您的问题?
  • @doxsi 当时的 stripExif 为我解决了问题。

标签: iphone xcode orientation uiimagepickercontroller


【解决方案1】:

在 UIImage 上设置 imageOrientation 标志,具体取决于拍摄照片时相机被握持的方式。这是一个只读标志,用于确定当您将图像放入视图时 iOS 将尝试显示图像的方向。

您可以在显示图像之前检查方向,并相应地操作 imageView。假设您在相同大小的视图中包含一个 imageView...

- (void) imagePickerImage:(UIImage*)image
{
    if (image.imageOrientation == UIImageOrientationUp ) {
        self.imageView.bounds = CGRectMake
           (0, 0, self.view.bounds.size.height, self.view.bounds.size.width);
        self.imageView.transform = CGAffineTransformMakeRotation(M_PI/2);

    } else if (image.imageOrientation == UIImageOrientationDown) {
        self.imageView.bounds = CGRectMake
           (0, 0, self.view.bounds.size.height, self.view.bounds.size.width);
        self.imageView.transform = CGAffineTransformMakeRotation(-M_PI/2);
    }
    else {
        self.imageView.bounds = self.view.bounds;
        self.imageView.transform = CGAffineTransformIdentity;
    }
    self.imageView.image = image;
}

另一种选择是从 imageRep 创建一个新图像:这应该去掉方向信息。

更新
iPhone 照片的原始像素尺寸是横向的,无论拍摄时手机的握持方式如何。只有方向 EXIF 标志设置不同。您无法更改 EXIF 标志,但可以通过将图像位图数据复制到新的位图图像来将其删除。另请参阅我的答案here

这是一种去除 EXIF 数据并添加纵向 EXIF 标志的方法。您正在创建一个新的 UIImage 并在创建时设置 EXIF 标志。您可以使用它来将横向图像标记为纵向 (UIImageOrientationRight)。

- (UIImage*)stripExif:(UIImage*)image
{
    CGImageRef cgImage = image.CGImage;
    UIImage* result = [UIImage imageWithCGImage:cgImage scale:1 
                                    orientation:UIImageOrientationRight];
    return result;
}

更新 2
将 UIImage 的 imageOrientation 属性称为 EXIF 标志是一种误导,原因有二:

(1) 图像元数据以字典式的结构存储,其中可以是多个子字典,其中一个是EXIF。其他包括例如 TIFF、IPTC、PNG。顶级字典中还有一组通用的标签。 orientation 键不在 EXIF 部分中,它位于 TIFF 和 IPTC 子词典(如果存在)中,也作为顶级键。当我们将图像元数据作为一个整体来引用时,我们倾向于使用术语 EXIF,但这是一种误导。

(2) 图像文件中的方向元数据使用一组不同于 Apple 在其 UIImage.imageOrientation 属性中使用的标志约定。因此,为了正确显示图像,您必须小心读取此属性。 Apple 显然使用图像文件的方向元数据来设置 UIImage 的属性,但有一些翻译正在进行。

 Orientation 

 Apple/UIImage.imageOrientation     Jpeg/File kCGImagePropertyOrientation

    UIImageOrientationUp    = 0  =  Landscape left  = 1
    UIImageOrientationDown  = 1  =  Landscape right = 3
    UIImageOrientationLeft  = 2  =  Portrait  down  = 8
    UIImageOrientationRight = 3  =  Portrait  up    = 6

Here is a page 显示“exif”旋转标志。与Apple's UIImage documentation(常量部分)进行比较。另请参阅 Apple 的 CGImageProperties_Reference,尤其是 kCGImagePropertyOrientation

我已经将一个小项目加载到 github 记录 various UIImage metadata issues

【讨论】:

  • 感谢您的回答。然而,问题不在于如何显示照片,而在于拍摄照片的尺寸。例如,当我将手机横向放置时,分辨率将为 3264 x 2448,而纵向则为 2448 x 3264。我将把我的问题改得更清楚。但是我明白了,不可能强制相机以特定方向拍照。
  • @DirkdeBoer 原生像素尺寸始终为横向 3264 x 2448 ......它是指示 NSImage 以哪种方式显示的方向标志。
  • @DirkdeBoer,摆脱 EXIF 方向标志的唯一方法是将照片中的位图数据复制到新的位图图像中。也许这就是您所追求的解决方案。
  • 实际上,您可以更改 EXIF 标志并以不同的方向保存图像。 setting exif data 是一个很好的开始。
  • 我明白了。这有点令人困惑,因为直接从 didFinishPickingMediaWithInfo 检查图像的分辨率会在横向和纵向中给出不同的分辨率。这可能是因为返回的值已经考虑了 imageOrientation。它给了我一个想法,即正在更改低(er)级别的相机分辨率,但显然情况并非如此。谢谢,我会接受你的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 2013-05-22
  • 2020-10-24
  • 2012-06-15
  • 1970-01-01
  • 2017-01-23
相关资源
最近更新 更多