10

我的应用程序中唯一允许的方向是横向。我在 target > 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;
4

1 回答 1

17

在 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标志,但可以通过将图像位图数据复制到新的位图图像来将其删除。另请参阅我的答案

这是一种去除 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。顶级字典中还有一组通用的标签。方向键不在 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

这是一个显示“exif”轮换标志的页面。与Apple 的 UIImage 文档(常量部分)进行比较。另请参阅 Apple 的CGImageProperties_Reference,尤其是kCGImagePropertyOrientation

我已经将一个小项目加载到 github 上,记录各种 UIImage 元数据问题

于 2013-01-23T23:25:53.257 回答