使用按钮向后/向前切换相机

时间:2018-03-30 10:42:15

标签: ios swift xcode camera

我目前在我的应用程序中有一个工作相机应用程序,并希望按钮调用前置或后置摄像头设备。我认为我已经获得了大部分就地代码,我唯一想知道的是如何编写按钮来调用这两个设备。

我已经尝试了一些if语句,但Xcode没有接受,这仍然是这个代码游戏的新手,通过实践来学习,但有时我遇到了冲击,所以任何帮助都会非常感激。

这是我使用的完整相机代码:

import Foundation
import UIKit
import AVFoundation

class CameraViewController: UIViewController{

var captureSession = AVCaptureSession()
var backCamera: AVCaptureDevice?
var frontCamera: AVCaptureDevice?
var currentCamera: AVCaptureDevice?

var photoOutput: AVCapturePhotoOutput?

var cameraPreviewLayer: AVCaptureVideoPreviewLayer?

var image: UIImage?

override func viewDidLoad() {
    super.viewDidLoad()

    setupCaptureSession()
    setupDevice()
    setupInputOutput()
    setupPreviewLayer()
    startRunningCaptureSession()
}

func setupCaptureSession() {
    captureSession.sessionPreset = AVCaptureSession.Preset.photo
}

func setupDevice() {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices {
        if device.position == AVCaptureDevice.Position.back {
            backCamera = device
        } else if device.position == AVCaptureDevice.Position.front {
            frontCamera = device
        }
    }

    currentCamera = frontCamera

}

func setupInputOutput() {
    do {
        let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
        captureSession.addInput(captureDeviceInput)
        photoOutput = AVCapturePhotoOutput()
        photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
        captureSession.addOutput(photoOutput!)
    } catch {
        print(error)
    }
}

func setupPreviewLayer() {
    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
    cameraPreviewLayer?.frame = self.view.frame
    self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)

}

func startRunningCaptureSession() {
    captureSession.startRunning()
}

@IBAction func cameraButton(_ sender: Any) {
    let settings = AVCapturePhotoSettings()
    photoOutput?.capturePhoto(with: settings, delegate: self)
    // performSegue(withIdentifier: "previewCameraPhoto", sender: nil)
}

@IBAction func switchCamera(_ sender: Any) {
    // The button which should switch the Cameras back an forth.  
}



override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "previewCameraPhoto" {
        let previewVC = segue.destination as! PreviewViewController
        previewVC.image = self.image
    }
}
}

extension CameraViewController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if let imageData = photo.fileDataRepresentation() {
        image = UIImage(data: imageData)
        performSegue(withIdentifier: "previewCameraPhoto", sender: nil)
    }
}

override var prefersStatusBarHidden: Bool
{
    return true
}
}

1 个答案:

答案 0 :(得分:1)

你不需要为backCamera,frontCamera,currentCamera声明变量,你只需要为AVCaptureDeviceInput保存变量。

试着评论:

//    var backCamera: AVCaptureDevice?
//    var frontCamera: AVCaptureDevice?
//    var currentCamera: AVCaptureDevice?

并添加:

var frontCameraDeviceInput: AVCaptureDeviceInput?
var backCameraDeviceInput: AVCaptureDeviceInput?

你的setupDevice函数看起来像这个

func setupDevice() {
    let frontCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)
    let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)

    frontCameraDeviceInput = try? AVCaptureDeviceInput(device: frontCamera!)
    backCameraDeviceInput = try? AVCaptureDeviceInput(device: backCamera!)
}

将setupInputOutput函数更改为:

func setupInputOutput() {
    captureSession.addInput(backCameraDeviceInput!)
    photoOutput = AVCapturePhotoOutput()
    photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
    captureSession.addOutput(photoOutput!)
}

最后你的switchCamera

@IBAction func switchCamera(_ sender: Any) {
        // The button which should switch the Cameras back an forth.

        captureSession.beginConfiguration()
        //Change camera device inputs from back to front or opposite
        if captureSession.inputs.contains(frontCameraDeviceInput!) == true {
            captureSession.removeInput(frontCameraDeviceInput!)
            captureSession.addInput(backCameraDeviceInput!)
        } else if captureSession.inputs.contains(backCameraDeviceInput!) == true {
            captureSession.removeInput(backCameraDeviceInput!)
            captureSession.addInput(frontCameraDeviceInput!)
        }

        //Commit all the configuration changes at once
        captureSession.commitConfiguration();
    }