本文自作自用笔记,不喜勿喷,诚谢纠错。
注意设置相机访问权限(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()
}
}