36

AVFoundation カメラが正しい向き (つまり、デバイスの向き) で写真をキャプチャできるようにしようとして、私は髪をかきむしってきましたが、それを機能させることができません。

チュートリアルを見たり、WWDC プレゼンテーションを見たり、WWDC サンプル プログラムをダウンロードしたりしましたが、それでもうまくいきません。

私のアプリのコードは...

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 は WWDC コードと同じ writeImage... メソッドを使用します)

WWDCアプリのコードは...

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

コードの冒頭で、彼らは AVOrientation を縦向きに設定しましたが、これは非常に奇妙に思えますが、デバイスの現在の向きを検出してそれを使用できるようにしようとしています。

ご覧のとおり、[UIApplication sharedApplication]statusBarOrientation を入れてこれを取得しようとしましたが、それでも写真は縦向きにしか保存されません。

私が何をする必要があるかについて誰か助けやアドバイスを提供できますか?

ありがとう!

オリバー

4

12 に答える 12

46

まあ、それは永遠にフラッキングにかかりましたが、私はそれをやった!

私が探していたコードのビットは

[UIDevice currentDevice].orientation;

そのまま入ります

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

そして、それは完全に機能します:D

ウープウープ!

于 2010-09-07T22:16:23.100 に答える
11

以下はAVCamからのもので、私も追加しました。

- (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];
}

そして、これをinitメソッドに必ず追加してください。

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[notificationCenter addObserver:self
    selector:@selector(deviceOrientationDidChange) 
    name:UIDeviceOrientationDidChangeNotification object:nil];
[self setOrientation:AVCaptureVideoOrientationPortrait];
于 2011-06-13T20:35:14.263 に答える
4

注意すべきことが2つあります

a)BrianKingが書いたように-LandscapeRightとLandscapeLeftは列挙で交換されます。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)ビデオの向きとして設定しようとすると、ビデオの録画に失敗するということもUIDeviceOrientationFaceUpあります。UIDeviceOrientationFaceDown電話をかけるときは使用しないでください[UIDevice currentDevice].orientation

于 2011-04-20T15:11:04.750 に答える
3

AVCaptureVideoPreviewLayer を使用している場合は、View Controller 内で次の操作を実行できます。

(「previewLayer」と呼ばれる AVCaptureVideoPreviewLayer のインスタンスがあると仮定します)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
   [self.previewLayer setOrientation:[[UIDevice currentDevice] orientation]];
}
于 2012-02-14T21:34:44.113 に答える
1

Swift では、次のようにする必要があります。

    videoOutput = AVCaptureVideoDataOutput()
    videoOutput!.setSampleBufferDelegate(self, queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL))

    if captureSession!.canAddOutput(self.videoOutput) {
        captureSession!.addOutput(self.videoOutput)
    }

    videoOutput!.connectionWithMediaType(AVMediaTypeVideo).videoOrientation = AVCaptureVideoOrientation.PortraitUpsideDown

それは私にとって完璧に機能します!

于 2015-11-27T18:46:03.740 に答える
1

これは、View Controller の向きの方法を使用します。これは私にとってはうまくいきます。うまくいけば、あなたにもうまくいきます。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    AVCaptureConnection *videoConnection = self.prevLayer.connection;
    [videoConnection setVideoOrientation:(AVCaptureVideoOrientation)toInterfaceOrientation];
}
于 2014-03-12T12:35:32.553 に答える
0

中間 CIImage を作成し、プロパティ ディクショナリを取得することもできます

NSDictionary *propDict = [aCIImage properties];
NSString *orientString = [propDict objectForKey:kCGImagePropertyOrientation];

それに応じて変換します:)

iOS5 では、このすべての画像メタデータに簡単にアクセスできる点が気に入っています!

于 2012-01-17T15:20:53.383 に答える
-1

AVCaptureFileOutputで使用する方法は?

- (void)detectVideoOrientation:(AVCaptureFileOutput *)captureOutput {
    for(int i = 0; i < [[captureOutput connections] count]; i++) {
        AVCaptureConnection *captureConnection = [[captureOutput connections] objectAtIndex:i];
        if([captureConnection isVideoOrientationSupported]) {
            [captureConnection setVideoOrientation:[[UIDevice currentDevice] orientation]];
        }
    }
}
于 2010-09-13T10:12:52.900 に答える