36 votes

iPhone AVFoundation orientation de la caméra

J'ai déchiré mes cheveux en essayant d'obtenir le AVFoundation appareil photo pour capturer une image dans le bon sens (c'est à dire l'orientation du périphérique) mais je ne peux pas le faire fonctionner.

J'ai regardé des tutoriels, j'ai regardé la WWDC de présentation et j'ai téléchargé la WWDC exemple de programme mais de même que ne pas le faire.

Le code de mon application est...

AVCaptureConnection *videoConnection = [CameraVC connectionWithMediaType:AVMediaTypeVideo fromConnections:[imageCaptureOutput connections]];
if ([videoConnection isVideoOrientationSupported])
{
    [videoConnection setVideoOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

[imageCaptureOutput captureStillImageAsynchronouslyFromConnection:videoConnection
                                                completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
    if (imageDataSampleBuffer != NULL)
    {
        //NSLog(@"%d", screenOrientation);

        //CMSetAttachment(imageDataSampleBuffer, kCGImagePropertyOrientation, [NSString stringWithFormat:@"%d", screenOrientation], 0);

        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
        UIImage *image = [[UIImage alloc] initWithData:imageData];

        [self processImage:image];
    }
}];

(processImage utilise le même writeImage... que la méthode de la WWDC code)

et le code de la WWDC application est...

AVCaptureConnection *videoConnection = [AVCamDemoCaptureManager connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]];
        if ([videoConnection isVideoOrientationSupported]) {
            [videoConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
        }

[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
                                                             completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
                                                                 if (imageDataSampleBuffer != NULL) {
                                                                     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                                                                     UIImage *image = [[UIImage alloc] initWithData:imageData];                                                                 
                                                                     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
                                                                     [library writeImageToSavedPhotosAlbum:[image CGImage]
                                                                                               orientation:(ALAssetOrientation)[image imageOrientation]
                                                                                           completionBlock:^(NSURL *assetURL, NSError *error){
                                                                                               if (error) {
                                                                                                   id delegate = [self delegate];
                                                                                                   if ([delegate respondsToSelector:@selector(captureStillImageFailedWithError:)]) {
                                                                                                       [delegate captureStillImageFailedWithError:error];
                                                                                                   }                                                                                               
                                                                                               }
                                                                                           }];
                                                                     [library release];
                                                                     [image release];
                                                                 } else if (error) {
                                                                     id delegate = [self delegate];
                                                                     if ([delegate respondsToSelector:@selector(captureStillImageFailedWithError:)]) {
                                                                         [delegate captureStillImageFailedWithError:error];
                                                                     }
                                                                 }
                                                             }];

Au début de leur code, ils ont mis le AVOrientaion portrait qui semble très étrange, mais je vais essayer de l'obtenir pour détecter le périphérique actuel de l'orientaion et l'utiliser.

Comme vous pouvez le voir j'ai mis [UIApplication sharedApplication]statusBarOrientation pour essayer et obtenir de ce, mais il reste qu'à enregistrer les photos en mode portrait.

Quelqu'un peut-il offrir de l'aide ou des conseils sur ce que je dois faire?

Merci!

Oliver

46voto

Fogmeister Points 21187

Eh bien, ça m'a pris de la fracture pour toujours mais je l'ai fait!

Le peu de code que je cherchais est

 [UIDevice currentDevice].orientation;
 

Cela va comme si

 AVCaptureConnection *videoConnection = [CameraVC connectionWithMediaType:AVMediaTypeVideo fromConnections:[imageCaptureOutput connections]];
if ([videoConnection isVideoOrientationSupported])
{
    [videoConnection setVideoOrientation:[UIDevice currentDevice].orientation];
}
 

Et ça marche parfaitement: D

Woop woop!

14voto

Bill Cheswick Points 339

N'est-ce pas un peu plus propre?

     AVCaptureVideoOrientation newOrientation;
    switch ([[UIDevice currentDevice] orientation]) {
    case UIDeviceOrientationPortrait:
        newOrientation = AVCaptureVideoOrientationPortrait;
        break;
    case UIDeviceOrientationPortraitUpsideDown:
        newOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
        break;
    case UIDeviceOrientationLandscapeLeft:
        newOrientation = AVCaptureVideoOrientationLandscapeRight;
        break;
    case UIDeviceOrientationLandscapeRight:
        newOrientation = AVCaptureVideoOrientationLandscapeLeft;
        break;
    default:
        newOrientation = AVCaptureVideoOrientationPortrait;
    }
    [stillConnection setVideoOrientation: newOrientation];
 

11voto

W Dyson Points 3144

Ce qui suit est de AVCam, j'ai aussi ajouté:

 - (void)deviceOrientationDidChange{

    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];

    AVCaptureVideoOrientation newOrientation;

    if (deviceOrientation == UIDeviceOrientationPortrait){
        NSLog(@"deviceOrientationDidChange - Portrait");
        newOrientation = AVCaptureVideoOrientationPortrait;
    }
    else if (deviceOrientation == UIDeviceOrientationPortraitUpsideDown){
        NSLog(@"deviceOrientationDidChange - UpsideDown");
        newOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
    }

    // AVCapture and UIDevice have opposite meanings for landscape left and right (AVCapture orientation is the same as UIInterfaceOrientation)
    else if (deviceOrientation == UIDeviceOrientationLandscapeLeft){
        NSLog(@"deviceOrientationDidChange - LandscapeLeft");
        newOrientation = AVCaptureVideoOrientationLandscapeRight;
    }
    else if (deviceOrientation == UIDeviceOrientationLandscapeRight){
        NSLog(@"deviceOrientationDidChange - LandscapeRight");
        newOrientation = AVCaptureVideoOrientationLandscapeLeft;
    }

    else if (deviceOrientation == UIDeviceOrientationUnknown){
        NSLog(@"deviceOrientationDidChange - Unknown ");
        newOrientation = AVCaptureVideoOrientationPortrait;
    }

    else{
        NSLog(@"deviceOrientationDidChange - Face Up or Down");
        newOrientation = AVCaptureVideoOrientationPortrait;
    }

    [self setOrientation:newOrientation];
}
 

Et n'oubliez pas d'ajouter ceci à votre méthode init:

 NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[notificationCenter addObserver:self
    selector:@selector(deviceOrientationDidChange) 
    name:UIDeviceOrientationDidChangeNotification object:nil];
[self setOrientation:AVCaptureVideoOrientationPortrait];
 

4voto

iRadium Points 41

il y a deux choses à remarquer

a) comme l'a écrit Brian King - LandscapeRight et LandscapeLeft sont échangés dans l'énumération. voir l'exemple d'AVCamCaptureManager:

 // AVCapture and UIDevice have opposite meanings for landscape left and right (AVCapture orientation is the same as UIInterfaceOrientation)
else if (deviceOrientation == UIDeviceOrientationLandscapeLeft)
    orientation = AVCaptureVideoOrientationLandscapeRight;
else if (deviceOrientation == UIDeviceOrientationLandscapeRight)
    orientation = AVCaptureVideoOrientationLandscapeLeft;
 

b) Il existe également UIDeviceOrientationFaceUp et UIDeviceOrientationFaceDown états, que si vous essayez de définir comme orientation vidéo, votre vidéo échouera à l'enregistrement. Assurez-vous de ne pas les utiliser lorsque vous appelez [UIDevice currentDevice].orientation !

3voto

Drew H Points 191

Si vous utilisez AVCaptureVideoPreviewLayer, vous pouvez effectuer les opérations suivantes dans votre contrôleur de vue.

(en supposant que vous ayez une instance de AVCaptureVideoPreviewLayer appelée "previewLayer")

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
   [self.previewLayer setOrientation:[[UIDevice currentDevice] orientation]];
}
 

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