UIImagePickerController相机预览是横向应用程序中的肖像

在我的风景iPhone应用程序中,我启动了一个UIImagePickerController来拍摄照片,但从相机显示的实时图像是纵向的,其周围有空白区域。 图像旋转。

一旦按下相机button,预览非常混乱,大部分的预览屏幕和视图不正确alignment。

苹果已经承认这是缺陷,正在努力。

我的问题是,有没有人有一个解决办法(合法或非法),让我现在得到这个工作。 我不会发布到App Store的非法修复,但我会有一个更好的用户testing应用程序 – 目前,相机是非常不可用的景观。

如果可以,我会附上一个简单的testing项目和图片。

编辑 – 为了澄清,我得到的图像是正确的景观。 我想要相机和预览用户界面看起来是正确的!


相机http://i42.tinypic.com/2zqsbpy.jpg

替代文字http://i43.tinypic.com/168zam0.jpg

答案比你想象的更荒谬。 我遇到了同样的问题,并在某个论坛上find了解决scheme。 将你拍摄的图像传递给像这样的方法:

// Code from: http://discussions.apple.com/thread.jspa?messageID=7949889 - (UIImage *)scaleAndRotateImage:(UIImage *)image { int kMaxResolution = 640; // Or whatever CGImageRef imgRef = image.CGImage; CGFloat width = CGImageGetWidth(imgRef); CGFloat height = CGImageGetHeight(imgRef); CGAffineTransform transform = CGAffineTransformIdentity; CGRect bounds = CGRectMake(0, 0, width, height); if (width > kMaxResolution || height > kMaxResolution) { CGFloat ratio = width/height; if (ratio > 1) { bounds.size.width = kMaxResolution; bounds.size.height = roundf(bounds.size.width / ratio); } else { bounds.size.height = kMaxResolution; bounds.size.width = roundf(bounds.size.height * ratio); } } CGFloat scaleRatio = bounds.size.width / width; CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); CGFloat boundHeight; UIImageOrientation orient = image.imageOrientation; switch(orient) { case UIImageOrientationUp: //EXIF = 1 transform = CGAffineTransformIdentity; break; case UIImageOrientationUpMirrored: //EXIF = 2 transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0); transform = CGAffineTransformScale(transform, -1.0, 1.0); break; case UIImageOrientationDown: //EXIF = 3 transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationDownMirrored: //EXIF = 4 transform = CGAffineTransformMakeTranslation(0.0, imageSize.height); transform = CGAffineTransformScale(transform, 1.0, -1.0); break; case UIImageOrientationLeftMirrored: //EXIF = 5 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width); transform = CGAffineTransformScale(transform, -1.0, 1.0); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationLeft: //EXIF = 6 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(0.0, imageSize.width); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationRightMirrored: //EXIF = 7 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeScale(-1.0, 1.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; case UIImageOrientationRight: //EXIF = 8 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; default: [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; } UIGraphicsBeginImageContext(bounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { CGContextScaleCTM(context, -scaleRatio, scaleRatio); CGContextTranslateCTM(context, -height, 0); } else { CGContextScaleCTM(context, scaleRatio, -scaleRatio); CGContextTranslateCTM(context, 0, -height); } CGContextConcatCTM(context, transform); CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return imageCopy; } 

🙁

我不认为你需要额外的工作来处理imageRotation或EXIF数据。 图像drawInRect将自动处理。

所以,你只需要得到这个大小或图像,并重新绘制一个新的形象,这就足够了。

捕捉后我不想旋转图像; 我想在横向模式下正确显示预览。 所以在iOS 6中,我在应用程序级允许纵向模式,但是将应用程序的根视图控制器设置为类MyNonrotatingNavigationController ,定义如下:

 @implementation MyNonrotatingNavigationController -(NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; } @end 

因此,在导航控制器中显示的所有内容都将处于横向模式(您可以使用任何视图控制器进行此操作)。 现在,当我需要显示图像select器时,我将应用程序窗口的根视图控制器replace为支持纵向模式的通用视图控制器。 为了防止旧的根视图控制器及其视图释放,我维护指针,直到我准备将它们放回到应用程序窗口。

 #define APP_DELEGATE ((MyAppDelegate*)[[UIApplication sharedApplication] delegate]) static UIViewController *pickerContainer = nil; static UIViewController *oldRoot = nil; static UIView *holdView = nil; -(void) showPicker { ...create UIImagePickerController... oldRoot = APP_DELEGATE.window.rootViewController; holdView = [[UIView alloc] initWithFrame:APP_DELEGATE.window.bounds]; [holdView addSubview:oldRoot.view]; pickerContainer = [UIViewController new]; pickerContainer.view = [[UIView alloc] initWithFrame:APP_DELEGATE.window.bounds]; APP_DELEGATE.window.rootViewController = pickerContainer; [pickerContainer presentViewController:picker animated:YES completion:NULL]; } -(void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info { [pickerContainer dismissViewControllerAnimated:YES completion:^{ dispatch_async( dispatch_get_main_queue(), ^{ APP_DELEGATE.window.rootViewController = oldRoot; [APP_DELEGATE.window addSubview:oldRoot.view]; pickerContainer = nil; oldRoot = nil; holdView = nil; }); }]; } 

一种痛苦,但它似乎适用于照片和video。 图像select器的控件以纵向模式显示,但应用程序的其余部分仅为横向模式。

我通过使UIImagePickerController以全屏模式出现,这也是苹果公司推荐的iPad解决了这个问题。

UIImagePickerController文档 :

在iPad上,如果您指定了UIImagePickerControllerSourceTypeCamera的源types,则可以以模态方式(全屏)或使用popup窗口来呈现图像select器。 但是,Applebuild议您仅以全屏方式呈现相机界面。

您需要将自定义视图(包含工具栏和标题)设置为cameraOverlayView ,还需要将allowsEditingshowsCameraControls设置为NO因为这会隐藏标准控件和预览。 这就是我在应用程序中发现的必要条件(我认为我需要select器是纵向的,但如果用户将设备旋转到横向,我需要应用一些UI更改)。 如果需要,可以提供代码。

PS在我的代码中还有一些错误,但我正在努力:)