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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14484816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 02:36:11  来源:igfitidea点击:

Force UIImagePickerController to take photo in portrait orientation/dimensions iOS

iphonexcodeorientationuiimagepickercontroller

提问by Dirk de Boer

The only allowed orientation in my app is landscape. I force this in the project properties under target > summery and only allow portrait in shouldAutorotateToInterfaceOrientation

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

The problem is when I take a picture while holding the phone horizontally (landscape), the photo will be taken in landscape orientation, while the UI remains in portrait mode.

问题是当我水平拿着手机(横向)拍照时,照片将以横向拍摄,而 UI 保持纵向模式。

This means in landscape mode I get a wide image of 3264 x 2448 instead of the tall image (2448 x 3264) I get in portrait mode.

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

Next the user can crop the image, but if the image is taken in landscape mode I get very ugly stretched images. Adding borders or switching the UI to landscape is not an option.

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

Is there a way to force the UIImagePickerControllerto take a photo in portrait dimensions even though the phone is held horizontally (landscape mode)?

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

I initialize the UIImagePickerControllerwith the following settings:

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;

回答by foundry

The imageOrientation flag is set on the UIImage depending on which way up the camera is being held when the picture is taken. This is a read-only flag and determines the orientation that iOS will attempt to display the image when you place it into a view.

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

You could check the orientation before displaying the image, and manipulate the imageView accordingly. Assuming you have an imageView enclosed inside a same-sized view...

您可以在显示图像之前检查方向,并相应地操作 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;
}

Another option could be to create a new image from an imageRep: this should strip out the orientation information.

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

update
The native pixel dimensions of an iPhone photograph are landscape, regardless of the way the phone is held when it is taken. It is only the orientation EXIFflag that is set differently. You cannot alter the EXIFflag but you can strip it out by copying the image bitmap data to a new bitmap image. See also my answers here.

更新
iPhone 照片的原始像素尺寸是横向的,与拍摄时手机的握持方式无关。只有方向EXIF标志设置不同。您无法更改EXIF标志,但可以通过将图像位图数据复制到新的位图图像来将其剥离。另见我的答案在这里

Here is a way to strip out the EXIFdata and add in a portrait EXIFflag. You are creating a new UIImage and setting the EXIFflag as you create it. You could use this to flag your landscape images as portrait (UIImageOrientationRight).

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

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

update 2
It is misleading to refer to the imageOrientation property of UIImage as an EXIF flag, for two reasons:

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

(1) image metadata is stored in a dictionary-style structure, within which can be a number of sub-dictionaries, one of which is EXIF. Others include TIFF, IPTC, PNG for example. There is also a general set of tags at the top-level dictionary. The orientationkey is NOT in the EXIF section, it is found in the TIFF and IPTC subdictionaries (if present) and also as a top-level key. We tend to use the term EXIF when referring to image metadata as a whole but this is misleading.

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

(2) Orientation metadata in the image file uses a different set of flag conventions to those that Apple uses in their UIImage.imageOrientation property. Therefore you have to take care if reading this property in order to display the image correctly. Apple evidently uses the image file's orientation metadata to set the UIImage's property, but there is a bit of translation going on.

(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 pageshowing 'exif' rotation flags. Compare with Apple's UIImage documentation(constants section). See also Apple's CGImageProperties_Reference, especially kCGImagePropertyOrientation

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

I have loaded a small project onto github logging various UIImage metadata issues

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