46 votes

UIImagePickerController aperçu de la caméra est portrait dans l'application paysage

Dans mon paysage seule application iPhone, je lance un UIImagePickerController pour prendre une photo, mais l'image affichée à partir de l'appareil photo est en orientation portrait, avec un espace vide autour d'elle. L'image est pivotée.

Une fois le bouton de la caméra est pressée, l'aperçu est très salissant, avec la plupart de l'aperçu de l'écran, et la vue n'est pas correctement aligné.

Apple a reconnu que c'est un défaut, et de travailler sur elle.

Ma question est, quelqu'un aurait-il une solution (légale ou illégale) qui me permettrait de le faire fonctionner maintenant. Je n'aurais pas communiqué de l'App Store avec une illégales corriger le problème, mais j'aurais une bien meilleure application pour le contrôle des utilisateurs - actuellement, la caméra est à peu près inutilisable en mode paysage.

Je vais joindre un simple projet de test et les images, si je peux.

Edit juste pour clarifier, l'image que j'obtiens est correctement paysage. Je veux que la caméra et le preview de l'Isu à regarder à droite!


Camera

alt text

88voto

Alex Wayne Points 58113

La réponse est plus ridicule que vous ne le pensez. J'ai eu le même problème et j'ai trouvé une solution quelque part dans un forum. Passez votre image prise dans une méthode comme celle-ci:

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

:(

1voto

user1319423 Points 11

Je ne pense pas que vous ayez besoin de travail supplémentaire pour gérer l'imageRotation ou les données EXIF. Image drawInRect s’occupera de cela automatiquement.

Il suffit donc d’obtenir cette taille ou cette image et de la redessiner pour une nouvelle image, cela suffirait.

1voto

jab Points 1836

Je ne veux pas faire pivoter l'image après la prise de vue; je veux avoir l'aperçu affiché correctement en mode paysage. Donc dans iOS 6, je laisse en mode portrait, au niveau de l'application, mais l'application de la vue de la racine de contrôleur de classe MyNonrotatingNavigationController, défini comme suit:

@implementation MyNonrotatingNavigationController

-(NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

@end

Donc, tout ce qui est jamais montré à l'intérieur de cette nav contrôleur sera en orientation paysage (vous pouvez le faire avec n'importe quelle vue contrôleur). Maintenant, quand j'ai besoin d'afficher une image picker, j'ai remplacer l'application de la fenêtre de vue de la racine de contrôleur avec un générique qui prend en charge le mode portrait. Pour prévenir la racine ancienne-vue-contrôleur et son point de vue à partir de la désallocation, je maintiens pointeurs vers eux jusqu'à ce que je suis prêt à les remettre dans la fenêtre d'application.

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

Une sorte de douleur, mais il ne semble pas fonctionner pour les photos et les vidéos. L'image du sélecteur de contrôles montrent en mode portrait, mais le reste de l'application est en mode paysage uniquement.

0voto

Ariel Points 1817

Vous devez régler l'affichage personnalisé(avec la barre d'outils et titre) comme cameraOverlayView, vous aurez également besoin de fixer allowsEditing et showsCameraControls de NO que vous pouvez masquer standart des contrôles et de la prévisualisation. C'est ce que j'ai trouvé comme nécessaire dans l'application que je suis en train de faire(la pensée, j'ai besoin de le sélecteur pour être en portrait, mais j'en ai besoin pour appliquer certains changements de l'interface si l'utilisateur de faire pivoter l'appareil en mode paysage). Le Code peut être fourni en cas de besoin.

P. S. Il y a encore quelques bugs dans mon code, mais j'y travaille :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X