代码之家  ›  专栏  ›  技术社区  ›  Fogmeister

iPhone AVFoundation相机方向

  •  35
  • Fogmeister  · 技术社区  · 15 年前

    我的应用程序的代码是。。。

    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使用相同的writeImage。。。方法(作为WWDC代码)

    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放在这里尝试获取此功能,但它仍然只保存肖像照片。

    谢谢!

    奥利弗

    11 回复  |  直到 10 年前
        1
  •  46
  •   Bhumit Mehta    11 年前

    好吧,我花了很长时间才用水力压裂,但我做到了!

    我要找的代码是

    [UIDevice currentDevice].orientation;
    

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

    呜呜!

        2
  •  14
  •   Bill Cheswick    12 年前

    这不是干净一点吗?

        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];
    
        3
  •  11
  •   Andrey Kuznetsov    14 年前

    以下是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];
    
        4
  •  4
  •   Max    15 年前

    有两件事要注意

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

        5
  •  3
  •   Drew H    14 年前

    如果您使用的是AVCaptureVideoPreviewLayer,您可以在视图控制器中执行以下操作。

    (假设您有一个名为“previewLayer”的AVCaptureVideoPreviewLayer实例)

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
       [self.previewLayer setOrientation:[[UIDevice currentDevice] orientation]];
    }
    
        6
  •  2
  •   Abdul Yasin    10 年前

    我正在用Swift写这段代码,以防有人需要。

    viewDidLoad )

        UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("deviceOrientationDidChange:"), name: UIDeviceOrientationDidChangeNotification, object: nil)
    

    第二步:拍照。在这里我们将交换方向 videoConnection LandscapeRight LandscapeLeft 还有维切弗萨

      func takePicture() {
    if let videoConnection = stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo) {
    
        var newOrientation: AVCaptureVideoOrientation?
        switch (UIDevice.currentDevice().orientation) {
        case .Portrait:
            newOrientation = .Portrait
            break
        case .PortraitUpsideDown:
            newOrientation = .PortraitUpsideDown
            break
        case .LandscapeLeft:
            newOrientation = .LandscapeRight
            break
        case .LandscapeRight:
            newOrientation = .LandscapeLeft
            break
        default :
            newOrientation = .Portrait
            break
    
        }
        videoConnection.videoOrientation = newOrientation!
    
    
      stillImageOutput!.captureStillImageAsynchronouslyFromConnection(videoConnection) {
        (imageDataSampleBuffer, error) -> Void in
    
        let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
    
          dispatch_async(dispatch_get_main_queue()) {
    
            let image = UIImage(data: imageData!)!
            let portraitImage = image.fixOrientation()
    
    
          }
        }
    
    
      }
    }
    
      }
    

    步骤3:固定方向(UIImage扩展)

    extension UIImage {
    
    func fixOrientation() -> UIImage {
    
        if imageOrientation == UIImageOrientation.Up {
            return self
        }
    
        var transform: CGAffineTransform = CGAffineTransformIdentity
    
        switch imageOrientation {
        case UIImageOrientation.Down, UIImageOrientation.DownMirrored:
            transform = CGAffineTransformTranslate(transform, size.width, size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
            break
        case UIImageOrientation.Left, UIImageOrientation.LeftMirrored:
            transform = CGAffineTransformTranslate(transform, size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
            break
        case UIImageOrientation.Right, UIImageOrientation.RightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
            break
        case UIImageOrientation.Up, UIImageOrientation.UpMirrored:
            break
        }
    
        switch imageOrientation {
        case UIImageOrientation.UpMirrored, UIImageOrientation.DownMirrored:
            CGAffineTransformTranslate(transform, size.width, 0)
            CGAffineTransformScale(transform, -1, 1)
            break
        case UIImageOrientation.LeftMirrored, UIImageOrientation.RightMirrored:
            CGAffineTransformTranslate(transform, size.height, 0)
            CGAffineTransformScale(transform, -1, 1)
        case UIImageOrientation.Up, UIImageOrientation.Down, UIImageOrientation.Left, UIImageOrientation.Right:
            break
        }
    
        let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(size.width), Int(size.height), CGImageGetBitsPerComponent(CGImage), 0, CGImageGetColorSpace(CGImage), CGImageAlphaInfo.PremultipliedLast.rawValue)!
    
        CGContextConcatCTM(ctx, transform)
    
        switch imageOrientation {
        case UIImageOrientation.Left, UIImageOrientation.LeftMirrored, UIImageOrientation.Right, UIImageOrientation.RightMirrored:
            CGContextDrawImage(ctx, CGRectMake(0, 0, size.height, size.width), CGImage)
            break
        default:
            CGContextDrawImage(ctx, CGRectMake(0, 0, size.width, size.height), CGImage)
            break
        }
    
        let cgImage: CGImageRef = CGBitmapContextCreateImage(ctx)!
    
        return UIImage(CGImage: cgImage)
    }
    
    
       }
    
        7
  •  2
  •   rockdaswift    7 年前

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        coordinator.animate(alongsideTransition: { [weak self] context in
            if let connection = self?.previewLayer?.connection, connection.isVideoOrientationSupported {
                if let orientation = AVCaptureVideoOrientation(orientation: UIDevice.current.orientation) {
                    connection.videoOrientation = orientation
                }
            }
        }, completion: nil)
        super.viewWillTransition(to: size, with: coordinator)
    }
    
    extension AVCaptureVideoOrientation {
        init?(orientation: UIDeviceOrientation) {
            switch orientation {
            case .landscapeRight: self = .landscapeLeft
            case .landscapeLeft: self = .landscapeRight
            case .portrait: self = .portrait
            case .portraitUpsideDown: self = .portraitUpsideDown
            default: return nil
            }
        }
    }
    
        8
  •  1
  •   Nate Hat    12 年前

    这将使用视图控制器的方向方法。这对我有用,希望对你有用。

    - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
    {
        [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    
        AVCaptureConnection *videoConnection = self.prevLayer.connection;
        [videoConnection setVideoOrientation:(AVCaptureVideoOrientation)toInterfaceOrientation];
    }
    
        9
  •  1
  •   vkalit    10 年前

    在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
    

        10
  •  1
  •   Pengguna    6 年前

    Swift 4和Swift 5。

    private var requests = [VNRequest]()
    let exifOrientation = exifOrientationFromDeviceOrientation()
    let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: exifOrientation, options: [:])
    do {
      try imageRequestHandler.perform(self.requests)
    } catch {
      print(error)
    }
    
    public func exifOrientationFromDeviceOrientation() -> CGImagePropertyOrientation {
        let curDeviceOrientation = UIDevice.current.orientation
        let exifOrientation: CGImagePropertyOrientation
    
        switch curDeviceOrientation {
        case UIDeviceOrientation.portraitUpsideDown:  // Device oriented vertically, home button on the top
            exifOrientation = .upMirrored
        case UIDeviceOrientation.landscapeLeft:       // Device oriented horizontally, home button on the right
            exifOrientation = .left
        case UIDeviceOrientation.landscapeRight:      // Device oriented horizontally, home button on the left
            exifOrientation = .right
        case UIDeviceOrientation.portrait:            // Device oriented vertically, home button on the bottom
            exifOrientation = .up
        default:
            exifOrientation = .up
        }
        return exifOrientation
    }
    
        11
  •  0
  •   johntraver    14 年前

    您还可以创建一个中间映像,并获取属性字典

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

    并相应变换:)

    我喜欢在iOS5中访问所有这些图像元数据是多么容易!

        12
  •  -1
  •   B.Asselin    15 年前

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