AVMediaTypeVideo捕获静止图像方向

时间:2015-07-15 17:21:07

标签: ios swift avfoundation

我已经看到了这个问题的其他几乎答案,但似乎无法让它发挥作用。我从AVMediaTypeVideo捕获图像,它的方向始终是UIImageOrientation 3(我不知道这实际意味着什么)。

我已尝试使用状态栏方向进行更正,但似乎没有任何效果。我不需要将这些图像保存到相机胶卷,它现在就在那里进行验证。我不确定这是否对方向有任何影响。

import UIKit
import AVFoundation

class ViewController: UIViewController {

let captureSession = AVCaptureSession()
let stillImageOutput = AVCaptureStillImageOutput()

var avCaptureVideoPreview : AVCaptureVideoPreviewLayer?

var error: NSError?

override func viewDidLoad() {
    super.viewDidLoad()

    let devices = AVCaptureDevice.devices().filter{ $0.hasMediaType(AVMediaTypeVideo) }

    if let captureDevice = devices.first as? AVCaptureDevice  {

        captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error))

        captureSession.sessionPreset = AVCaptureSessionPresetMedium

        captureSession.startRunning()

        stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]

        if captureSession.canAddOutput(stillImageOutput) {

            captureSession.addOutput(stillImageOutput)
        }

        avCaptureVideoPreview = AVCaptureVideoPreviewLayer(session: captureSession)

        if let previewLayer = avCaptureVideoPreview {

            previewLayer.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height)

            previewLayer.position = CGPointMake(view.bounds.midX, view.bounds.midY)

            previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

            let cameraPreview = UIView(frame: CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height))

            cameraPreview.layer.addSublayer(previewLayer)

            cameraPreview.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"saveToCamera:"))

            view.addSubview(cameraPreview)
        }
    }

    // Add a selfie button if device is capable

    for device in devices {

        if device.position == AVCaptureDevicePosition.Front {

            // Add selfie button
            println("selfie capable")
        }

    }

}

override func viewWillLayoutSubviews() {

    if avCaptureVideoPreview != nil {

        // Orientation

        if (avCaptureVideoPreview!.connection.supportsVideoOrientation == true) {

            avCaptureVideoPreview!.connection.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.sharedApplication().statusBarOrientation)
        }

        // Frame 

        avCaptureVideoPreview!.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height)

        avCaptureVideoPreview!.position = CGPointMake(view.bounds.midX, view.bounds.midY)

        avCaptureVideoPreview!.videoGravity = AVLayerVideoGravityResizeAspectFill

    }
}

func interfaceOrientationToVideoOrientation(orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation {

    switch orientation {

    case UIInterfaceOrientation.Portrait:
        return AVCaptureVideoOrientation.Portrait
    case UIInterfaceOrientation.PortraitUpsideDown:
        return AVCaptureVideoOrientation.PortraitUpsideDown
    case UIInterfaceOrientation.LandscapeLeft:
        return AVCaptureVideoOrientation.LandscapeLeft
    case UIInterfaceOrientation.LandscapeRight:
        return AVCaptureVideoOrientation.LandscapeRight
    default:
        return AVCaptureVideoOrientation.Portrait

    }

}

func saveToCamera(sender: UITapGestureRecognizer) {

    if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) {

        stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {

            (imageDataSampleBuffer, error) -> Void in

            var image = UIImage(data: AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer))

            // this is not working
            var orientation : UIImageOrientation?

            switch UIApplication.sharedApplication().statusBarOrientation.rawValue {

            case 1:
                orientation = UIImageOrientation.Up
            case 3:
                orientation = UIImageOrientation.Left
            case 4:
                orientation = UIImageOrientation.Right
            default:
                orientation = UIImageOrientation.Up

            }

            let newImage = UIImage(CGImage: image?.CGImage, scale: 1.0, orientation: orientation!)

            UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil)

        }
    }
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}

1 个答案:

答案 0 :(得分:3)

编辑,这不适用于使用前置摄像头拍摄的照片,它们在原生照片应用程序中显示正常,但在Mac上的照片中共享或从parse.com加载时不能显示。

感谢@XJones在这里的回答Why does AVCaptureVideoOrientation landscape modes result in upside down still images?

import UIKit
import AVFoundation

class ViewController: UIViewController {

let captureSession = AVCaptureSession()
let stillImageOutput = AVCaptureStillImageOutput()

var avCaptureVideoPreview : AVCaptureVideoPreviewLayer?

var error: NSError?

override func viewDidLoad() {
    super.viewDidLoad()

    let devices = AVCaptureDevice.devices().filter{ $0.hasMediaType(AVMediaTypeVideo) }

    if let captureDevice = devices.first as? AVCaptureDevice  {

        captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error))

        captureSession.sessionPreset = AVCaptureSessionPresetMedium

        captureSession.startRunning()

        stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]

        if captureSession.canAddOutput(stillImageOutput) {

            captureSession.addOutput(stillImageOutput)
        }

        avCaptureVideoPreview = AVCaptureVideoPreviewLayer(session: captureSession)

        if let previewLayer = avCaptureVideoPreview {

            previewLayer.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height)

            previewLayer.position = CGPointMake(view.bounds.midX, view.bounds.midY)

            previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

            let cameraPreview = UIView(frame: CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height))

            cameraPreview.layer.addSublayer(previewLayer)

            cameraPreview.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"saveToCamera:"))

            view.addSubview(cameraPreview)
        }
    }

    // Add a selfie button if device is capable

    for device in devices {

        if device.position == AVCaptureDevicePosition.Front {

            // Add selfie button
            println("selfie capable")
        }

    }

}

override func viewWillLayoutSubviews() {

    if avCaptureVideoPreview != nil {

        // Orientation

        if (avCaptureVideoPreview!.connection.supportsVideoOrientation == true) {

            var newOrientation : AVCaptureVideoOrientation?

            switch UIDevice.currentDevice().orientation {
            case UIDeviceOrientation.Portrait:
                newOrientation = AVCaptureVideoOrientation.Portrait
            case UIDeviceOrientation.PortraitUpsideDown:
                newOrientation = AVCaptureVideoOrientation.PortraitUpsideDown
            case UIDeviceOrientation.LandscapeLeft:
                newOrientation = AVCaptureVideoOrientation.LandscapeRight;
            case UIDeviceOrientation.LandscapeRight:
                newOrientation = AVCaptureVideoOrientation.LandscapeLeft
            default:
                newOrientation = AVCaptureVideoOrientation.Portrait
            }

            avCaptureVideoPreview!.connection.videoOrientation = newOrientation!

        }

        // Frame 

        avCaptureVideoPreview!.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height)

        avCaptureVideoPreview!.position = CGPointMake(view.bounds.midX, view.bounds.midY)

        avCaptureVideoPreview!.videoGravity = AVLayerVideoGravityResizeAspectFill

    }
}

func saveToCamera(sender: UITapGestureRecognizer) {

    if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) {

        stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {

            (imageDataSampleBuffer, error) -> Void in

            var image = UIImage(data: AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer))

            var imageOrientation : UIImageOrientation?

            switch UIDevice.currentDevice().orientation {

            case UIDeviceOrientation.PortraitUpsideDown:
                imageOrientation = UIImageOrientation.Left
            case UIDeviceOrientation.LandscapeRight:
                imageOrientation = UIImageOrientation.Down
            case UIDeviceOrientation.LandscapeLeft:
                imageOrientation = UIImageOrientation.Up
            case UIDeviceOrientation.Portrait:
                imageOrientation = UIImageOrientation.Right
            default:
                imageOrientation = UIImageOrientation.Right

            }

            var newImage = UIImage(CGImage: image!.CGImage, scale: 1.0, orientation: imageOrientation!)

            UIImageWriteToSavedPhotosAlbum(newImage!, nil, nil, nil)

        }
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}