强制UIImagePickerController以纵向/尺寸iOS拍摄照片

Dir*_*oer 10 iphone xcode orientation uiimagepickercontroller

我的应用中唯一允许的方向是横向.我在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;
Run Code Online (Sandbox Code Playgroud)

fou*_*dry 17

imageOrientation标志在UIImage上设置,具体取决于拍摄照片时相机的保持方向.这是一个只读标志,用于确定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;
}
Run Code Online (Sandbox Code Playgroud)

另一种选择可能是从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;
}
Run Code Online (Sandbox Code Playgroud)

更新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
Run Code Online (Sandbox Code Playgroud)

这是一个显示'exif'旋转标志的页面.与Apple的UIImage文档(常量部分)比较.又见苹果CGImageProperties_Reference,尤其是kCGImagePropertyOrientation

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