2009-02-11 87 views
43

在我的横向专用iPhone应用程序中,我启动了UIImagePickerController来拍摄照片,但从摄像头显示的实时图像是纵向的,其周围有空白区域。图像旋转。UIImagePickerController摄像头预览是横向应用中的纵向

按下相机按钮后,预览非常混乱,大部分预览画面不对,视图未正确对齐。

苹果已经承认这是缺陷,并且正在研究它。

我的问题是,有没有人有一个解决办法(合法或非法),让我现在得到这个工作。我不会在非法修复的情况下发布到App Store,但是我会为用户测试提供更好的应用 - 目前相机在景观上几乎不可用。

我会附上一个简单的测试项目和图像,如果我可以。

编辑 - 为了澄清,我得到的图像是正确的景观。我希望相机&预览用户界面看起来不错!


Camera http://i42.tinypic.com/2zqsbpy.jpg

alt text http://i43.tinypic.com/168zam0.jpg

+5

就像NFL裁判说的,“非法修补,进攻,10码,第二下。” – gonzobrains 2011-07-07 19:22:01

+5

这很奇怪,因为我不知道NFL是什么。 – 2011-08-05 08:09:20

+0

奇怪我们北美人(注意:北美不包括美国)假设每个人都知道NFL是什么! @JaneSales代表国家橄榄球联盟,它与你所认识的足球实际上不同。 – 2013-09-06 19:13:57

回答

87

答案是比你想象的更可笑。我遇到了同样的问题,并在某个论坛上找到了解决方案。通过您所拍摄的图像变成这样一个方法:

// 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; 
} 

:(

0

你需要设置自定义视图(工具栏和标题)为cameraOverlayView,你也需要设置allowsEditingshowsCameraControlsNO,因为这将隐藏标准控件和预览。 这就是我在应用程序中发现的必要条件(我认为我需要选择器是纵向的,但如果用户旋转,我需要它来应用一些UI更改他的设备为风景)如果需要,可以提供代码

P.S.我的代码中仍然存在一些错误,但我正在努力:)

1

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

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

1

我不想在捕获后旋转图像;我想在横向模式下正确显示预览。因此,在iOS 6中,我允许在应用层面人像模式,但设置的应用程序根视图控制器是MyNonrotatingNavigationController类,定义如下:

@implementation MyNonrotatingNavigationController 

-(NSUInteger) supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskLandscape; 
} 

@end 
认为是有史以来该导航控制器内所示

所以一切都将在横向(你可以用任何视图控制器来做到这一点)。现在,当我需要显示图像选择器时,我将应用程序窗口的根视图控制器替换为支持纵向模式的通用视图控制器。为了防止旧的根视图控制器及其视图解除分配,我保持指向它们的指针,直到我准备将它们放回到应用程序窗口中。

#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; 
     }); 
    }]; 
} 

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

1

我解决了这个问题,使UIImagePickerController以全屏模式出现,这也是Apple推荐给iPad的。

UIImagePickerController documentation

在iPad上,如果指定UIImagePickerControllerSourceTypeCamera的源类型,可以存在于图像拾取模态(全画面)或通过使用酥料饼。但是,Apple建议您仅以全屏方式呈现相机界面。

相关问题