zoukankan      html  css  js  c++  java
  • swift3.0自定义相机界面

    这是公司上上上一个项目的自定义相机界面,原来是swift2.0写的,今天改为swift3.0,记录一下.

    效果图如下:

                                                                                                                                                                                                                          

    使用AVFoundation制作.

    属性:

     1     var device:AVCaptureDevice!   //获取设备:如摄像头
     2     var input:AVCaptureDeviceInput!   //输入流
     3     var photoOutput:AVCaptureStillImageOutput! //输出流
     4     var  output:AVCaptureMetadataOutput! //当启动摄像头开始捕获输入
     5     var  session:AVCaptureSession!//会话,协调着intput到output的数据传输,input和output的桥梁
     6     var  previewLayer:AVCaptureVideoPreviewLayer! //图像预览层,实时显示捕获的图像
     7     
     8     var photoButton: UIButton?   //拍照按钮
     9     var imageView: UIImageView?   //拍照后的成像
    10     var image: UIImage?   //拍照后的成像
    11     var isJurisdiction: Bool?   //是否获取了拍照标示
    12     var flashBtn:UIButton?  //闪光灯按钮

    在viewDidLoad里面判断下权限,没给权限给个提示

            isJurisdiction = canUserCamear()
            if isJurisdiction! {
                customCamera()  //自定义相机
                customUI()  //自定义相机按钮
            }
            else {
                return
            }
        // MARK: - 检查相机权限
        func canUserCamear() -> Bool {
            let authStatus: AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
            if authStatus == .denied {
                let alertView = UIAlertView(title: "请打开相机权限", message: "设置-隐私-相机", delegate: self, cancelButtonTitle: "确定", otherButtonTitles: "取消")
                alertView.tag = 100
                alertView.show()
                return false
            }
            else {
                return true
            }
            return true
        }

    自定义相机:

     1  //MARK: 初始化自定义相机
     2     func customCamera(){
     3        guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { return } //初始化摄像头设备
     4         guard let device = devices.filter({ return $0.position == .back }).first else{ return}
     5         self.device = device
     6         //输入流初始化
     7         self.input = try? AVCaptureDeviceInput(device: device)
     8         //照片输出流初始化
     9         self.photoOutput = AVCaptureStillImageOutput.init()
    10         //输出流初始化
    11         self.output = AVCaptureMetadataOutput.init()
    12         //生成会话
    13         self.session = AVCaptureSession.init()
    14         if(self.session.canSetSessionPreset("AVCaptureSessionPreset1280x720")){
    15             self.session.sessionPreset = "AVCaptureSessionPreset1280x720"
    16         }
    17         if(self.session.canAddInput(self.input)){
    18             self.session.addInput(self.input)
    19         }
    20         if(self.session.canAddOutput(self.photoOutput)){
    21             self.session.addOutput(self.photoOutput)
    22         }
    23         //使用self.session,初始化预览层,self.session负责驱动input进行信息的采集,layer负责把图像渲染显示
    24         self.previewLayer = AVCaptureVideoPreviewLayer.init(session: self.session)
    25         self.previewLayer.frame  = CGRect.init(x: 0, y: 0,  kScreenWH.width, height: kScreenWH.height)
    26         self.previewLayer.videoGravity = "AVLayerVideoGravityResizeAspectFill"
    27         self.view.layer.addSublayer(self.previewLayer)
    28         //启动
    29         self.session.startRunning()
    30         if ((try? device.lockForConfiguration()) != nil) {
    31             if device.isFlashModeSupported(.auto) {
    32                 device.flashMode = .auto
    33             }
    34             //自动白平衡
    35             if device.isWhiteBalanceModeSupported(.autoWhiteBalance) {
    36                 device.whiteBalanceMode = .autoWhiteBalance
    37             }
    38             device.unlockForConfiguration()
    39         }
    40         
    41         //闪光灯
    42         do{ try device.lockForConfiguration() }catch{ }
    43         if device.hasFlash == false { return }
    44         device.flashMode = AVCaptureFlashMode.auto
    45         device.unlockForConfiguration()
    46         
    47     }
    View Code

    自定义相机界面按钮:拍照,取消,闪光灯,前后拍照切换按钮

     1 //MARK: 添加自定义按钮等UI
     2     func customUI(){
     3        //前后摄像头切换
     4         let changeBtn = UIButton.init()
     5         changeBtn.frame = CGRect.init(x: kScreenWH.width - 50, y: 20,  40, height: 40)
     6         changeBtn.setImage(#imageLiteral(resourceName: "change"), for: .normal)
     7         changeBtn.addTarget(self, action: #selector(self.changeCamera), for: .touchUpInside)
     8         view.addSubview(changeBtn)
     9         
    10         //拍照按钮
    11         photoButton = UIButton(type: .custom)
    12         photoButton?.frame = CGRect(x: kScreenWH.width * 1 / 2.0 - 30, y: kScreenWH.height - 100,  60, height: 60)
    13         photoButton?.setImage(UIImage(named: "photograph"), for: .normal)
    14         photoButton?.setImage(UIImage(named: "photograph_Select"), for: .normal)
    15         photoButton?.addTarget(self, action: #selector(self.shutterCamera), for: .touchUpInside)
    16         view.addSubview(photoButton!)
    17         
    18       //闪光灯按钮
    19         flashBtn = UIButton.init()
    20         flashBtn?.frame = CGRect.init(x: 10, y: 20,  40, height: 40)
    21         flashBtn?.addTarget(self, action: #selector(self.flashAction), for: .touchUpInside)
    22         flashBtn?.setImage(#imageLiteral(resourceName: "flash-A"), for: .normal)
    23         view.addSubview(flashBtn!)
    24         
    25        //取消
    26         let cancelBtn = UIButton.init()
    27         cancelBtn.frame = CGRect.init(x: 10, y: kScreenWH.height - 100,  60, height: 60)
    28         cancelBtn.setTitle("取消", for: .normal)
    29         cancelBtn.addTarget(self, action: #selector(self.cancelActin), for: .touchUpInside)
    30         view.addSubview(cancelBtn)
    31     }
    32     //MARK:前后摄像头更改事件
    33     func changeCamera(){
    34         //获取之前的镜头
    35         guard var position = input?.device.position else { return }
    36         //获取当前应该显示的镜头
    37         position = position == .front ? .back : .front
    38         //创建新的device
    39         guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { return }
    40         // 1.2.取出获取前置摄像头
    41         let d = devices.filter({ return $0.position == position }).first
    42         device = d
    43         //input
    44         guard let videoInput = try? AVCaptureDeviceInput(device: d) else { return }
    45 
    46         //切换
    47         session.beginConfiguration()
    48         session.removeInput(self.input!)
    49         session.addInput(videoInput)
    50         session.commitConfiguration()
    51         self.input = videoInput
    52         
    53     }
    View Code

    拍照按钮点击事件:

     1     //MARK:拍照按钮点击事件
     2     func shutterCamera(){
     3         let videoConnection: AVCaptureConnection? = photoOutput.connection(withMediaType: AVMediaTypeVideo)
     4         if videoConnection == nil {
     5             print("take photo failed!")
     6             return
     7         }
     8         photoOutput.captureStillImageAsynchronously(from: videoConnection ?? AVCaptureConnection(), completionHandler: {(_ imageDataSampleBuffer: CMSampleBuffer?, _ error: Error?) -> Void in
     9             if imageDataSampleBuffer == nil {
    10                 return
    11             }
    12             let imageData: Data? = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)   //照片数据流
    13             self.image = UIImage(data: imageData!)
    14             self.session.stopRunning()
    15             self.imageView = UIImageView(frame: self.previewLayer.frame)
    16             self.view.insertSubview(self.imageView!, belowSubview: self.photoButton!)
    17             self.imageView?.layer.masksToBounds = true
    18             self.imageView?.image = self.image
    19             print("image size = (NSStringFromCGSize((self.image?.size)!))")
    20         })
    21     }
    View Code

    闪光灯切换事件:

     1     //MARK: 闪光灯开关
     2     func flashAction(){
     3         try? device.lockForConfiguration()
     4         switch device.flashMode.rawValue {
     5         case 0:
     6             device!.flashMode = AVCaptureFlashMode.on
     7             flashBtn?.setImage(#imageLiteral(resourceName: "flash-on"), for: .normal)
     8             break
     9         case 1:
    10         device!.flashMode = AVCaptureFlashMode.auto
    11         flashBtn?.setImage(#imageLiteral(resourceName: "flash-A"), for: .normal)
    12             break
    13         default:
    14          device!.flashMode = AVCaptureFlashMode.off
    15             flashBtn?.setImage(#imageLiteral(resourceName: "flash-off"), for: .normal)
    16         }
    17         device.unlockForConfiguration()
    18         
    19     }
    View Code

    取消按钮点击事件:

        //MARK:取消按钮
        func cancelActin(){
            self.imageView?.removeFromSuperview()
            self.session.startRunning()
        }

    github源码地址:https://github.com/pheromone/swift_custom_camera

  • 相关阅读:
    python学习:字符编码与转码
    python学习:文件操作
    python学习:基本运算符
    python学习:列表、元组、字典、集合
    python学习:基础知识
    linux常用命令
    hadoop手动安全模式
    System.getProperty("user.dir")的理解
    如何获取SpringBoot项目的applicationContext对象
    spring无法注入bean
  • 原文地址:https://www.cnblogs.com/shaoting/p/7346722.html
Copyright © 2011-2022 走看看