【问题标题】:Fix orientation for custom camera app iOS修复自定义相机应用 iOS 的方向
【发布时间】:2019-07-19 04:51:24
【问题描述】:

基于自定义相机教程:https://github.com/brianadvent/CustomCamera

尝试从它构建。观察到相机没有按预期旋转。应用程序在纵向模式下完美运行,但在横向模式下却在意想不到的模式下运行。在横向模式下,相机视图没有像默认相机那样平移。

查看之前的帖子,例如:cannot change AVCaptureVideoDataOutput orientation

但是这些过时的帖子。因此不得不重新发布。

纵向模式的屏幕截图:

横向模式下的屏幕截图:

下面是ViewController.swift的代码。

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    let captureSession = AVCaptureSession()
    var previewLayer:CALayer!
    var captureDevice:AVCaptureDevice!
    var takePhoto = false

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        prepareCamera()
    }

    func prepareCamera() {
        captureSession.sessionPreset = AVCaptureSession.Preset.photo
        if let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices.first {
            captureDevice = availableDevices
            beginSession()
        }
    } // prepareCamera

    func beginSession () {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
            captureSession.addInput(captureDeviceInput)
        }catch {
            print(error.localizedDescription)
        }

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

        self.previewLayer = previewLayer
        self.view.layer.addSublayer(self.previewLayer)
        self.previewLayer.frame = self.view.layer.frame
        captureSession.startRunning()

        let dataOutput = AVCaptureVideoDataOutput()
        dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString):NSNumber(value:kCVPixelFormatType_32BGRA)] as [String : Any]
        dataOutput.alwaysDiscardsLateVideoFrames = true

        if captureSession.canAddOutput(dataOutput) {
            captureSession.addOutput(dataOutput)
        }

        captureSession.commitConfiguration()


        let queue = DispatchQueue(label: "com.brianadvent.captureQueue")
        dataOutput.setSampleBufferDelegate(self, queue: queue)
    }

    @IBAction func takePhoto(_ sender: Any) {
        takePhoto = true

    }

    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
        if takePhoto {
            takePhoto = false

            if let image = self.getImageFromSampleBuffer(buffer: sampleBuffer) {

                let photoVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoVC") as! PhotoViewController
                photoVC.takenPhoto = image
                DispatchQueue.main.async {
                    self.present(photoVC, animated: true, completion: { 
                        self.stopCaptureSession()
                    })
                } // dispatch
            } // if image
        } //takePhoto
    } // captureOutput


    func getImageFromSampleBuffer (buffer:CMSampleBuffer) -> UIImage? {
        if let pixelBuffer = CMSampleBufferGetImageBuffer(buffer) {
            let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
            let context = CIContext()

            let imageRect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer))

            if let image = context.createCGImage(ciImage, from: imageRect) {
                return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .right)
            }
        } // if pixelBuffer

        return nil
    } // getImageFromSampleBuffer

    func stopCaptureSession () {
        self.captureSession.stopRunning()

        if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
            for input in inputs {
                self.captureSession.removeInput(input)
            }
        }

    } // stopCaptureSession


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    } // didReceiveMemoryWarning


}

【问题讨论】:

    标签: ios swift iphone camera


    【解决方案1】:

    第 1 步:检查 AVCaptureConnection isVideoOrientationSupported 与否

    第 2 步:如果是,则设置 AVCaptureConnection 纵向或横向右的 VideoOrientation。

    用这个函数替换你的问题就解决了。

    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
    
        if takePhoto {
            takePhoto = false
            if connection.isVideoOrientationSupported {
                connection.videoOrientation = UIDevice.current.orientation == .portrait ? .portrait : .landscapeRight
            }
            if let image = self.getImageFromSampleBuffer(buffer: sampleBuffer) {
    
                let photoVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoVC") as! PhotoViewController
    
                photoVC.takenPhoto = image
    
                DispatchQueue.main.async {
                    self.present(photoVC, animated: true, completion: {
                        self.stopCaptureSession()
                    })
    
                }
            }
    
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      我已经用

      改变了方向
      detectionOverlay.setAffineTransform(CGAffineTransform(rotationAngle: CGFloat(.pi / 0.5)).scaledBy(x: scale, y: -scale))
      

      captureConnection?.videoOrientation = .landscapeRight
      

      这是一个我使用 LandscapeRight 检测对象的演示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-21
        • 2013-12-02
        • 1970-01-01
        • 1970-01-01
        • 2013-07-16
        相关资源
        最近更新 更多