swift3.0自定义相机界面

时间:2022-12-16 21:59:12

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

效果图如下:

                                                                                                                              swift3.0自定义相机界面

使用AVFoundation制作.

属性:

     var device:AVCaptureDevice!   //获取设备:如摄像头
var input:AVCaptureDeviceInput! //输入流
var photoOutput:AVCaptureStillImageOutput! //输出流
var output:AVCaptureMetadataOutput! //当启动摄像头开始捕获输入
var session:AVCaptureSession!//会话,协调着intput到output的数据传输,input和output的桥梁
var previewLayer:AVCaptureVideoPreviewLayer! //图像预览层,实时显示捕获的图像 var photoButton: UIButton? //拍照按钮
var imageView: UIImageView? //拍照后的成像
var image: UIImage? //拍照后的成像
var isJurisdiction: Bool? //是否获取了拍照标示
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 =
alertView.show()
return false
}
else {
return true
}
return true
}

自定义相机:

  //MARK: 初始化自定义相机
func customCamera(){
guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { return } //初始化摄像头设备
guard let device = devices.filter({ return $.position == .back }).first else{ return}
self.device = device
//输入流初始化
self.input = try? AVCaptureDeviceInput(device: device)
//照片输出流初始化
self.photoOutput = AVCaptureStillImageOutput.init()
//输出流初始化
self.output = AVCaptureMetadataOutput.init()
//生成会话
self.session = AVCaptureSession.init()
if(self.session.canSetSessionPreset("AVCaptureSessionPreset1280x720")){
self.session.sessionPreset = "AVCaptureSessionPreset1280x720"
}
if(self.session.canAddInput(self.input)){
self.session.addInput(self.input)
}
if(self.session.canAddOutput(self.photoOutput)){
self.session.addOutput(self.photoOutput)
}
//使用self.session,初始化预览层,self.session负责驱动input进行信息的采集,layer负责把图像渲染显示
self.previewLayer = AVCaptureVideoPreviewLayer.init(session: self.session)
self.previewLayer.frame = CGRect.init(x: , y: , width: kScreenWH.width, height: kScreenWH.height)
self.previewLayer.videoGravity = "AVLayerVideoGravityResizeAspectFill"
self.view.layer.addSublayer(self.previewLayer)
//启动
self.session.startRunning()
if ((try? device.lockForConfiguration()) != nil) {
if device.isFlashModeSupported(.auto) {
device.flashMode = .auto
}
//自动白平衡
if device.isWhiteBalanceModeSupported(.autoWhiteBalance) {
device.whiteBalanceMode = .autoWhiteBalance
}
device.unlockForConfiguration()
} //闪光灯
do{ try device.lockForConfiguration() }catch{ }
if device.hasFlash == false { return }
device.flashMode = AVCaptureFlashMode.auto
device.unlockForConfiguration() }

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

 //MARK: 添加自定义按钮等UI
func customUI(){
//前后摄像头切换
let changeBtn = UIButton.init()
changeBtn.frame = CGRect.init(x: kScreenWH.width - , y: , width: , height: )
changeBtn.setImage(#imageLiteral(resourceName: "change"), for: .normal)
changeBtn.addTarget(self, action: #selector(self.changeCamera), for: .touchUpInside)
view.addSubview(changeBtn) //拍照按钮
photoButton = UIButton(type: .custom)
photoButton?.frame = CGRect(x: kScreenWH.width * / 2.0 - , y: kScreenWH.height - , width: , height: )
photoButton?.setImage(UIImage(named: "photograph"), for: .normal)
photoButton?.setImage(UIImage(named: "photograph_Select"), for: .normal)
photoButton?.addTarget(self, action: #selector(self.shutterCamera), for: .touchUpInside)
view.addSubview(photoButton!) //闪光灯按钮
flashBtn = UIButton.init()
flashBtn?.frame = CGRect.init(x: , y: , width: , height: )
flashBtn?.addTarget(self, action: #selector(self.flashAction), for: .touchUpInside)
flashBtn?.setImage(#imageLiteral(resourceName: "flash-A"), for: .normal)
view.addSubview(flashBtn!) //取消
let cancelBtn = UIButton.init()
cancelBtn.frame = CGRect.init(x: , y: kScreenWH.height - , width: , height: )
cancelBtn.setTitle("取消", for: .normal)
cancelBtn.addTarget(self, action: #selector(self.cancelActin), for: .touchUpInside)
view.addSubview(cancelBtn)
}
//MARK:前后摄像头更改事件
func changeCamera(){
//获取之前的镜头
guard var position = input?.device.position else { return }
//获取当前应该显示的镜头
position = position == .front ? .back : .front
//创建新的device
guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { return }
// 1.2.取出获取前置摄像头
let d = devices.filter({ return $.position == position }).first
device = d
//input
guard let videoInput = try? AVCaptureDeviceInput(device: d) else { return } //切换
session.beginConfiguration()
session.removeInput(self.input!)
session.addInput(videoInput)
session.commitConfiguration()
self.input = videoInput }

拍照按钮点击事件:

     //MARK:拍照按钮点击事件
func shutterCamera(){
let videoConnection: AVCaptureConnection? = photoOutput.connection(withMediaType: AVMediaTypeVideo)
if videoConnection == nil {
print("take photo failed!")
return
}
photoOutput.captureStillImageAsynchronously(from: videoConnection ?? AVCaptureConnection(), completionHandler: {(_ imageDataSampleBuffer: CMSampleBuffer?, _ error: Error?) -> Void in
if imageDataSampleBuffer == nil {
return
}
let imageData: Data? = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) //照片数据流
self.image = UIImage(data: imageData!)
self.session.stopRunning()
self.imageView = UIImageView(frame: self.previewLayer.frame)
self.view.insertSubview(self.imageView!, belowSubview: self.photoButton!)
self.imageView?.layer.masksToBounds = true
self.imageView?.image = self.image
print("image size = \(NSStringFromCGSize((self.image?.size)!))")
})
}

闪光灯切换事件:

     //MARK: 闪光灯开关
func flashAction(){
try? device.lockForConfiguration()
switch device.flashMode.rawValue {
case :
device!.flashMode = AVCaptureFlashMode.on
flashBtn?.setImage(#imageLiteral(resourceName: "flash-on"), for: .normal)
break
case :
device!.flashMode = AVCaptureFlashMode.auto
flashBtn?.setImage(#imageLiteral(resourceName: "flash-A"), for: .normal)
break
default:
device!.flashMode = AVCaptureFlashMode.off
flashBtn?.setImage(#imageLiteral(resourceName: "flash-off"), for: .normal)
}
device.unlockForConfiguration() }

取消按钮点击事件:

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

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

swift3.0自定义相机界面的更多相关文章

  1. swift3.0 自定义键盘

    ...绕了一大圈,又绕回原生来了,今天,学习一下swift3.0语法下的自定义键盘.效果图如下: 其实,很简单,只需要把UITextView(或者UITextField)的inputView属性设置为 ...

  2. swift3.0 创建经典界面的九宫图

    网络上很多例子都是早期的 Object-C的效果,现在用到Swift3.0开发,故把网络上的例子翻译过来,达到基本的效果.可是现在这个还不算很满意,再下次继续进行优化 override func vi ...

  3. Swift3.0 自定义tableView复用cell 的写法,与CollectionViewCell的不同,数据model

    Model数据 class HospitalModel: NSObject { //后边不赋值 会报错 var imgurl :String = "" var introducti ...

  4. 如何用uniapp+vue开发自定义相机插件——拍照+录像功能

    调用手机的相机功能并实现拍照和录像是很多APP与插件都必不可少的一个功能,今天智密科技就来分享一下如何基于uniapp + vue实现自定义相机界面,并且实现: 1: 自定义拍照 2: 自定义录像 3 ...

  5. Swift2.3 --> Swift3.0 的变化

    Swift3.0语法变化 首先和大家分享一下学习新语法的技巧: 用Xcode8打开自己的Swift2.3的项目,选择Edit->Convert->To Current Swift Synt ...

  6. Android相机使用(系统相机、自定义相机、大图片处理)

    本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人Surf ...

  7. Android自定义相机拍照、图片裁剪的实现

    最近项目里面又要加一个拍照搜题的功能,也就是用户对着不会做的题目拍一张照片,将照片的文字使用ocr识别出来,再调用题库搜索接口搜索出来展示给用户,类似于小猿搜题.学霸君等app. 其实Android提 ...

  8. Swift3.0语法变化

    写在前面 首先和大家分享一下学习新语法的技巧:用Xcode8打开自己的Swift2.3的项目,选择Edit->Convert->To Current Swift Syntax- 让Xcod ...

  9. Android调用系统相机以及自定义相机

    0.综述 自定义相机,此处展示简单的相机功能,官方文档中还有相应关于视频拍摄的内容,此处不提 1.添加权限 <!--相机权限,数据存储--> <uses-permission and ...

随机推荐

  1. 电子数字 网易游戏在线笔试 第一题 hihocoder

    题目链接 http://hihocoder.com/contest/ntest2016spring1/problem/1 这个题目有几个算法考点: (1)对于一个LED数码管(由7个发光二极管封装在一 ...

  2. Codrops 教程:实现内容倾斜的 3D 幻灯片效果

    今天给大家分享的优秀教程来自 Codrops 网站,实现一个内容倾斜的 3D 幻灯片效果.我们平常见到的都是那种水平或者垂直滚动的效果,这个倾斜的内容滑动效果相信会让你眼前一亮.因为使用了 CSS 3 ...

  3. HDU 2822 &lpar;BFS&plus;优先队列&rpar;

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2822 题目大意:X消耗0,.消耗1, 求起点到终点最短消耗 解题思路: 每层BFS的结点,优先级不同 ...

  4. 如何用ABBYY把PDF如何转换成HTML

    将PDF转换成HTML网页格式,是快速打造专业级网站的方法之一.当用户找到了非常详实的PDF资料,打算将之制作成为网页格式时,如果重新开发往往需要耗费大量的时间,可是又不知道怎么样才可以将PDF文件转 ...

  5. linux挂载问题解决

    1. 挂载光盘 </pre></p><p><pre name="code" class="plain">[roo ...

  6. 关于PHP伪静态Rewrite设置

    Rewirte主要的功能就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则 表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等   一.Apache配置:   1.支持httpd ...

  7. Windows Phone 的控件倾斜效果

    原文:Windows Phone 的控件倾斜效果 Windows Phone 7的系统设置里,按钮都有一个点击倾斜的效果,但自己添加的控件就没有.但微软提供了这个效果的代码:TiltEffect MS ...

  8. Struts Chain ClassCastException Aop

    我们知道struts的restult type 有很多,但主要就是四种 dispatch,rediret,chain,drdirectaction 要让数据从一个action传到另一个action,就 ...

  9. &period;NET Core开发日志——依赖注入

    依赖注入(DI)不是一个新的话题,它的出现是伴随着系统解耦的需要而几乎必然产生的. 在SOLID设计原则中,DIP(Dependency inversion principle)--依赖倒置,规定了& ...

  10. Book Review 《构建之法》-2

    -敏捷流程包括了几大原则:Backlog.burn-down.Sprint.Scrum. 敏捷开发注重个人之间的交流,提倡尽早的交付有价值的软件满足顾客的需求, 在开发过程中不断与客户进行交互,变化. ...