2009-02-11 88 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建議您僅以全屏方式呈現相機界面。

相關問題