2009-02-11 3 views
43

In meiner Landscape-only iPhone-Anwendung, starte ich einen UIImagePickerController, um ein Foto zu machen, aber das Live-Bild von der Kamera angezeigt wird im Hochformat, mit Leerzeichen um es herum. Das Bild wird gedreht.UIImagePickerController Kamera Vorschau ist Porträt in Landschaft App

Sobald die Kamerataste gedrückt wird, ist die Vorschau sehr unordentlich, die meisten der Vorschau aus dem Bildschirm und Ansichten nicht richtig ausgerichtet.

Apple hat bestätigt, dass dies ein Fehler ist, und arbeitet daran.

Meine Frage ist, hat jemand eine Umgehung (legal oder illegal), die es mir erlauben würde, dies jetzt zu arbeiten. Ich würde nicht mit einem illegalen Update in den App Store veröffentlichen, aber ich hätte eine viel bessere App für die Nutzer testen - derzeit ist die Kamera in der Landschaft ziemlich unbrauchbar.

Ich werde ein einfaches Testprojekt und Bilder beifügen, wenn ich kann.

Bearbeiten - nur um zu klären, das Bild, das ich bekomme, ist richtig Landschaft. Ich möchte die Kamera & Vorschau UIs richtig aussehen!


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

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

+5

Gesprochen wie ein NFL-Schiedsrichter, "Illegal fix, Offensive. 10 Yards. Zweite unten." – gonzobrains

+5

Das ist seltsam, weil ich keine Ahnung habe, was NFL ist. –

+0

Seltsam, wie wir Nordamerikaner (Anmerkung: Nordamerika schließt nicht nur USA ein) nehmen Sie an, jeder weiß, was die NFL ist! @JaneSales steht für die National Football League, die eigentlich anders ist als der Fußball, den du kennst. –

Antwort

87

Die Antwort ist lächerlicher als Sie vielleicht denken. Ich hatte das selbe Problem und fand irgendwo eine Lösung in einem Forum. Fahren Sie mit aufgenommenes Bild in ein Verfahren wie folgt aus:

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

lächerlich, aber es funktioniert :) – byron

+0

super Methode, wirklich seine Arbeit! – freelancer

+0

Vielen Dank für diese Methode! Das rotierende Thema hat mich fast verrückt gemacht! – applefreak

0

Sie müssen benutzerdefinierte Ansicht einstellen (mit Symbolleiste und Titel) als cameraOverlayView, auch müssen Sie allowsEditing und showsCameraControls einstellen Das ist, was ich in der App, die ich mache, als notwendig gefunden habe (ich denke, ich brauche den Picker im Portrait, aber ich brauche ihn, um einige Änderungen vorzunehmen, wenn der Benutzer rotiert sein Gerät zu Landschaft). Code kann zur Verfügung gestellt werden, wenn es nötig ist.

P.S. Es gibt immer noch einige Fehler in meinem Code, aber ich arbeite daran :)

1

Ich denke nicht, dass Sie die zusätzliche Arbeit benötigen, um mit imageRotation oder den EXIF-Daten überhaupt umzugehen. Image drawInRect wird das automatisch erledigen.

Also, Sie müssen nur diese Größe oder das Bild und neu zu einem neuen Bild neu zu zeichnen, das wäre genug.

1

Ich möchte das Bild nach der Aufnahme nicht drehen; Ich möchte die Vorschau im Querformat korrekt anzeigen lassen. So in iOS 6, erlaube ich Portrait-Modus auf der Anwendungsebene, sondern setzen Sie die Root-Ansicht-Controller App der Klasse MyNonrotatingNavigationController, definiert wie folgt:

@implementation MyNonrotatingNavigationController 

-(NSUInteger) supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskLandscape; 
} 

@end 

Also alles, was je ist in diesem nav-Controller angezeigt wird in Querformat (Sie können dies mit jedem View-Controller machen). Wenn ich nun eine Bildauswahl anzeigen muss, ersetze ich den Stammansicht-Controller des Anwendungsfensters durch ein generisches, das den Hochformatmodus unterstützt. Um zu verhindern, dass der alte Root-View-Controller und seine Ansichten freigegeben werden, verwalte ich Zeiger auf sie, bis ich sie wieder in das App-Fenster einfügen kann.

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

Eine Art von Schmerz, aber es scheint für Fotos und Videos zu arbeiten. Die Steuerelemente der Bildauswahl werden im Hochformat angezeigt, der Rest der App ist jedoch nur im Querformat.

+0

Awesome Workaround, funktioniert auch auf iOS7. –

1

Ich löste dieses Problem, indem ich das UIImagePickerController im Vollbildmodus erscheinen ließ, was Apple auch für iPad empfiehlt.

Von UIImagePickerController documentation:

auf iPad, wenn Sie eine Quelltyp UIImagePickerControllerSourceTypeCamera angeben, können Sie das Bild Picker modal präsentieren (Vollbild) oder durch einen popover verwenden. Apple empfiehlt jedoch, die Kameraoberfläche nur im Vollbildmodus darzustellen.

Verwandte Themen