本文自作自用笔记,不喜勿喷,诚谢纠错。

注意设置相机访问权限(http://www.cnblogs.com/lc901221/p/6599644.html),走起,上代码。

 

import UIKit

import AVFoundation

let WIDTH = UIScreen.main.bounds.width

let HEIGHT = UIScreen.main.bounds.height

class LCCaremaViewController: UIViewController{    

    // 音视频采集会话

    let captureSession = AVCaptureSession()

    // 后置摄像头

    var backFacingCamera: AVCaptureDevice?

    // 前置摄像头

    var frontFacingCamera: AVCaptureDevice?

    // 当前正在使用的设备

    var currentDevice: AVCaptureDevice?

    // 静止图像输出端

    var stillImageOutput: AVCaptureStillImageOutput?

    // 相机预览图层

    var cameraPreviewLayer:AVCaptureVideoPreviewLayer?

    //切换手势

    var toggleCameraGestureRecognizer = UISwipeGestureRecognizer()

    //放大手势

    var zoomInGestureRecognizer = UISwipeGestureRecognizer()

    //缩小手势

    var zoomOutGestureRecognizer = UISwipeGestureRecognizer()

    //照片拍摄后预览视图

    var photoImageview:UIImageView!

    //照相按钮

    var photoBtn:UIButton!

    //取消按钮/重拍

    var cancel:UIButton!

    //保存按钮

    var save:UIButton!

    override func viewDidLoad() {

        super.viewDidLoad()

         //获取设备,创建UI

        self.CreateUI()

        //给当前view创建手势

        self.CreateGestureRecognizer()

        // 创建拍照按钮

        self.createPhotoBtn()

        //view.bringSubview(toFront: cameraButton)

    }

    //MARK: - 获取设备,创建自定义视图

    func CreateUI(){

         // 将音视频采集会话的预设设置为高分辨率照片--选择照片分辨率

        self.captureSession.sessionPreset = AVCaptureSession.Preset.hd1280x720

        // 获取设备

        let devices = AVCaptureDevice.devices(for: AVMediaType.video)

         for device in devices {

                 if device.position == AVCaptureDevice.Position.back {

                self.backFacingCamera = device

              }

            else if device.position == AVCaptureDevice.Position.front {

                self.frontFacingCamera = device

             }

        }

        //设置当前设备为前置摄像头

         self.currentDevice = self.backFacingCamera

          do {

                // 当前设备输入端

             let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)

              self.stillImageOutput = AVCaptureStillImageOutput()

            // 输出图像格式设置

            self.stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]

            self.captureSession.addInput(captureDeviceInput)

            self.captureSession.addOutput(self.stillImageOutput!)

            }

          catch {

             print(error)

              return

            }

           // 创建预览图层

         self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

         self.view.layer.addSublayer(cameraPreviewLayer!)

         self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill

         self.cameraPreviewLayer?.frame = view.layer.frame

        // 启动音视频采集的会话

        self.captureSession.startRunning()

    }

     //MARK: - 创建手势

    func CreateGestureRecognizer(){

        // 上滑手势控制前置和后置摄像头的转换

        self.toggleCameraGestureRecognizer.direction = .up

        self.toggleCameraGestureRecognizer.addTarget(self, action: #selector(self.toggleCamera))

        self.view.addGestureRecognizer(toggleCameraGestureRecognizer)

        // 右滑放大

        self.zoomInGestureRecognizer.direction = .right

        self.zoomInGestureRecognizer.addTarget(self, action: #selector(self.zoomIn))

        self.view.addGestureRecognizer(zoomInGestureRecognizer)

        // 左滑缩小

        self.zoomOutGestureRecognizer.direction = .left

        self.zoomOutGestureRecognizer.addTarget(self, action: #selector(self.zoomOut))

        self.view.addGestureRecognizer(zoomOutGestureRecognizer)

    }

    func createPhotoBtn(){

        //创建照相按钮

        self.photoBtn = UIButton.init(frame: CGRect.init(x: WIDTH/2 - 50, y: HEIGHT - 100, width: 100, height: 80))

        self.photoBtn.setTitle("拍照", for: .normal)

        self.photoBtn.setTitleColor(UIColor.red, for: .normal)

        self.view.addSubview(self.photoBtn)

        self.view.bringSubview(toFront: self.photoBtn)

        // 创建预览照片视图

        self.photoImageview = UIImageView.init(frame: self.view.frame)

        self.view.addSubview(self.photoImageview)

        self.photoImageview.isHidden = true

        //

   self.cancel = UIButton.init(frame: CGRect.init(x: 50, y: HEIGHT - 100, width: 100, height: 80))

        self.cancel.setTitle("重拍", for: .normal)

        self.cancel.setTitleColor(UIColor.red, for: .normal)

        self.photoImageview.addSubview(self.cancel)

       self.cancel.addTarget(self, action: #selector(self.cancelAction), for: .touchUpInside)

        self.save = UIButton.init(frame: CGRect.init(x:WIDTH - 150, y: HEIGHT - 100, width: 100, height: 80))

        self.save.setTitle("保存", for: .normal)

        self.save.setTitleColor(UIColor.red, for: .normal)

        self.photoImageview.addSubview(self.save)

        self.photoImageview.isUserInteractionEnabled = true

        self.save.addTarget(self, action: #selector(self.saveAction), for: .touchUpInside)

        self.photoBtn.addTarget(self, action: #selector(self.photoAction), for: .touchUpInside)

    }

    //照相按钮

    @objc func photoAction(){

     // 获得音视频采集设备的连接

        let videoConnection = stillImageOutput?.connection(with: AVMediaType.video)

        // 输出端以异步方式采集静态图像

        stillImageOutput?.captureStillImageAsynchronously(from: videoConnection!, completionHandler: { (imageDataSampleBuffer, error) -> Void in

             // 获得采样缓冲区中的数据

             let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer!)

          // 将数据转换成UIImage

           if let stillImage = UIImage(data: imageData!) {

               //显示当前拍摄照片

             self.photoImageview.isHidden = false

              self.photoImageview.image = stillImage

       }

       })

    }

  //取消按钮/重拍

  @objc func cancelAction(){

    //隐藏Imageview

       self.photoImageview.isHidden = true

   }

  //保存按钮-保存到相册

 @objc func saveAction(){

      //保存照片到相册

     UIImageWriteToSavedPhotosAlbum(self.photoImageview.image!, nil, nil, nil)

        self.cancelAction()

     }

 }

extension LCCaremaViewController{

    //MARK: - 放大方法

      @objc func zoomIn() {

       if let zoomFactor = currentDevice?.videoZoomFactor {

       if zoomFactor < 5.0 {

            let newZoomFactor = min(zoomFactor + 1.0, 5.0)

                do {

                    try currentDevice?.lockForConfiguration()

                    currentDevice?.ramp(toVideoZoomFactor: newZoomFactor, withRate: 1.0)

           currentDevice?.unlockForConfiguration()

            }

               catch {

                     print(error)

                }

             }

         }

    }

    //MARK: - 缩小方法

     @objc func zoomOut() {

        if let zoomFactor = currentDevice?.videoZoomFactor {

           if zoomFactor > 1.0 {

               let newZoomFactor = max(zoomFactor - 1.0, 1.0)

              do {

                   try currentDevice?.lockForConfiguration()

                    currentDevice?.ramp(toVideoZoomFactor: newZoomFactor, withRate: 1.0)

                    currentDevice?.unlockForConfiguration()

                }

                catch {

                    print(error)

                }

            }

        }

    }

      //MARK: - 切换摄像头

        @objc func toggleCamera() {

        captureSession.beginConfiguration()

           // 在前置和后置之间切换摄像头

         let newDevice = (currentDevice?.position == AVCaptureDevice.Position.back) ? frontFacingCamera : backFacingCamera

          // 移除之前所有的输入会话

         for input in captureSession.inputs {

             captureSession.removeInput(input as! AVCaptureDeviceInput)

        }

        // 将输入端切换到新的采集设备

        let cameraInput: AVCaptureDeviceInput

        do {

            cameraInput = try AVCaptureDeviceInput(device: newDevice!)

        }

        catch {

            print(error)

           return

         }

        // 添加输入端

        if captureSession.canAddInput(cameraInput) {

            captureSession.addInput(cameraInput)

        }

        currentDevice = newDevice

         // 提交配置

          captureSession.commitConfiguration()

    }

}