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

问题是当我水平握住手机(风景)时拍照时,照片将以风景方向拍摄,而UI仍保持为纵向模式。

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

接下来,用户可以裁剪图像,但是如果以横向模式拍摄图像,我会得到非常丑陋的拉伸(stretch)图像。添加边框或将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;

最佳答案

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

您可以在显示图像之前检查方向,并相应地操作imageView。假设您在相同大小的 View 中包含了一个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照片的 native 像素尺寸是横向的,而与拍摄时握住手机的方式无关。仅方向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。顶级字典中还有一组常规标签。方向键不在EXIF部分中,可以在TIFF和IPTC子词典(如果有)中找到,也可以用作顶层键。当整体上涉及图像元数据时,我们倾向于使用术语EXIF,但这会产生误导。

(2)图像文件中的方向元数据使用与Apple在其UIImage.imageOrientation属性中使用的标志约定不同的标志约定。因此,如果要正确显示图像,必须阅读此属性。苹果显然使用图像文件的方向元数据来设置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

10-07 19:13
查看更多