54

そこで、Apple の指示に従って、 http://developer.apple.com/iphone/library/qa/qa2010/qa1702.html を使用してビデオ セッションをキャプチャしAVCaptureSessionまし。私が直面している問題の 1 つは、カメラ/iPhone デバイスの向きが垂直 (および はAVCaptureVideoPreviewLayer垂直カメラ ストリームを表示) であるにもかかわらず、出力画像が横向きモードになっているように見えることです。サンプルコード内の imageBuffer の width と height を確認したimageFromSampleBuffer:ところ、それぞれ 640px と 480px でした。なぜこれが事実なのか誰か知っていますか?

ありがとう!

4

11 に答える 11

44

ヘッダー AVCaptureSession.h を見てください。AVCaptureVideoOrientationさまざまなビデオの向きを定義すると呼ばれる列挙型の定義があります。AVCaptureConnection オブジェクトには、videoOrientation と呼ばれるプロパティがありますAVCaptureVideoOrientation。これを設定して、ビデオの向きを変更できるはずです。おそらくAVCaptureVideoOrientationLandscapeRightまたはが必要AVCaptureVideoOrientationLandscapeLeftです。

セッションの出力を見ると、セッションの AVCaptureConnections を見つけることができます。出力には、その出力の接続の配列である connections プロパティがあります。

于 2010-08-25T02:06:15.737 に答える
23

皆さん、これを難しくしています。

DidOutputSampleBuffer では、画像を取得する前に方向を変更するだけです。それはモノですが、あなたは持っています

    public class OutputRecorder : AVCaptureVideoDataOutputSampleBufferDelegate {    
        public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
        {
            try {
                connection.videoOrientation = AVCaptureVideoOrientation.LandscapeLeft;

objCではこのメソッドです

- ( void ) captureOutput: ( AVCaptureOutput * ) captureOutput
   didOutputSampleBuffer: ( CMSampleBufferRef ) sampleBuffer
      fromConnection: ( AVCaptureConnection * ) connection
于 2014-11-05T16:12:54.620 に答える
22

向きの問題を修正するために、 に簡単な 1 行の変更を加えましたimageFromSampleBuffer(「I modified ...」の下のコードのコメントを参照してください)。私はこれにあまりにも多くの時間を費やしたので、それが誰かを助けることを願っています.

// Create a UIImage from sample buffer data
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer  {
    // Get a CMSampleBuffer's Core Video image buffer for the media data
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // Lock the base address of the pixel buffer
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Get the number of bytes per row for the pixel buffer
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    // Get the number of bytes per row for the pixel buffer
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    // Get the pixel buffer width and height
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    // Create a device-dependent RGB color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // Create a bitmap graphics context with the sample buffer data
    CGContextRef context1 = CGBitmapContextCreate(baseAddress, width, height, 8, 
                                                 bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

    // Create a Quartz image from the pixel data in the bitmap graphics context
    CGImageRef quartzImage = CGBitmapContextCreateImage(context1); 
    // Unlock the pixel buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // Free up the context and color space
    CGContextRelease(context1); 
    CGColorSpaceRelease(colorSpace);

    // Create an image object from the Quartz image
    //I modified this line: [UIImage imageWithCGImage:quartzImage]; to the following to correct the orientation:
    UIImage *image =  [UIImage imageWithCGImage:quartzImage scale:1.0 orientation:UIImageOrientationRight]; 

    // Release the Quartz image
    CGImageRelease(quartzImage);

    return (image);
}
于 2012-07-21T19:31:11.957 に答える
16

正しいシーケンスは次のとおりです。

AVCaptureVideoDataOutput *videoCaptureOutput = [[AVCaptureVideoDataOutput alloc] init];

if([self.captureSession canAddOutput:self.videoCaptureOutput]){
    [self.captureSession addOutput:self.videoCaptureOutput];
}else{
    NSLog(@"cantAddOutput");
}

// set portrait orientation
AVCaptureConnection *conn = [self.videoCaptureOutput connectionWithMediaType:AVMediaTypeVideo];
[conn setVideoOrientation:AVCaptureVideoOrientationPortrait];
于 2014-02-09T13:35:11.050 に答える
2

方向の問題は前面カメラにあるため、デバイスの種類を確認して新しい画像を生成すると、方向の問題が確実に解決されます。

-(void)capture:(void(^)(UIImage *))handler{

AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in self.stillImageOutput.connections)
{
    for (AVCaptureInputPort *port in [connection inputPorts])
    {
        if ([[port mediaType] isEqual:AVMediaTypeVideo] )
        {
            videoConnection = connection;
            break;
        }
    }
    if (videoConnection) { break; }
}

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {

    if (imageSampleBuffer != NULL) {
        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
        **UIImage *capturedImage = [UIImage imageWithData:imageData];
        if (self.captureDevice == [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][1]) {
            capturedImage = [[UIImage alloc] initWithCGImage:capturedImage.CGImage scale:1.0f orientation:UIImageOrientationLeftMirrored];
        }**

        handler(capturedImage);
    }
}];
}
于 2014-10-18T13:38:57.760 に答える
1
// #1
AVCaptureVideoOrientation newOrientation = AVCaptureVideoOrientationLandscapeRight;
if (@available(iOS 13.0, *)) {
    // #2
    for (AVCaptureConnection *connection in [captureSession connections]) {
        if ([connection isVideoOrientationSupported]) {
            connection.videoOrientation = newOrientation;
            break;
        }
    } // #3
} else if ([previewLayer.connection isVideoOrientationSupported]) {
    previewLayer.connection.videoOrientation = newOrientation;
}

を正しく使用できるようAVCaptureSessionになったら、ビデオの向きを設定できます。ここでは、上記のコードの詳細な説明です。このコードは、実行[captureSession startRunning]実行する必要があることに注意してください。

  1. お好みの向きをお選びください
  2. iOS バージョン >= 13.0 の場合、アクティブな接続を から取得する必要がありますcaptureSession。注意: ビデオ接続のみがサポートされていますvideoOrientation
  3. iOS バージョン < 13.0 の場合、previewLayer

viewController の向きが固定されていない場合はvideoOrientation、デバイスの向きが変わったら接続に新しい を設定できます。

于 2020-04-07T08:55:20.587 に答える
-1

これを試すことができます:

private func startLiveVideo() {

    let captureSession = AVCaptureSession()
    captureSession.sessionPreset = .photo
    let captureDevice = AVCaptureDevice.default(for: .video)

    let input = try! AVCaptureDeviceInput(device: captureDevice!)
    let output = AVCaptureVideoDataOutput()
    captureSession.addInput(input)
    captureSession.addOutput(output)

    output.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
    output.connection(with: .video)?.videoOrientation = .portrait

    let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = view.bounds
    view.layer.addSublayer(previewLayer)

    captureSession.startRunning()
}
于 2017-11-16T21:14:21.753 に答える