这篇文章主要为大家详细介绍了iOS 10自定义相机功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了iOS 10自定义相机功能的具体代码,供大家参考,具体内容如下
直接上代码
//
// TGCameraVC.swift
// TGPhotoPicker
//
// Created by targetcloud on 2017/7/25.
// Copyright © 2017年 targetcloud. All rights reserved.
//
import UIKit
import AVFoundation
import Photos
@available(iOS 10.0, *)
class TGCameraVC: UIViewController {
var callbackPicutureData: ((Data?) -> ())?
private var device: AVCaptureDevice?
private var input: AVCaptureDeviceInput?
private var imageOutput: AVCapturePhotoOutput?
private var session: AVCaptureSession?
private var previewLayer: AVCaptureVideoPreviewLayer?
fileprivate var showImageContainerView: UIView?
fileprivate var showImageView: UIImageView?
fileprivate var picData: Data?
private var flashMode: AVCaptureFlashMode = .auto
private weak var flashButton: UIButton?
override func viewDidLoad() {
super.viewDidLoad()
setupCamera()
setupUI()
if #available(iOS 9.0, *) {
let isVCBased = Bundle.main.infoDictionary?["UIViewControllerBasedStatusBarAppearance"] as? Bool ?? false
if !isVCBased{
UIApplication.shared.setStatusBarHidden(false, with: .none)
}
}else {
UIApplication.shared.statusBarStyle = .lightContent
UIApplication.shared.setStatusBarHidden(false, with: .none)
}
}
override var prefersStatusBarHidden: Bool{
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
private func setupCamera() {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { success in
if !success {
let alertVC = UIAlertController(title: TGPhotoPickerConfig.shared.cameraUsage, message: TGPhotoPickerConfig.shared.cameraUsageTip, preferredStyle: .actionSheet)
alertVC.addAction(UIAlertAction(title: TGPhotoPickerConfig.shared.confirmTitle, style: .default, handler: nil))
self.present(alertVC, animated: true, completion: nil)
}
}
device = cameraWithPosistion(.back)
input = try? AVCaptureDeviceInput(device: device)
guard input != nil else {
return
}
imageOutput = AVCapturePhotoOutput()
session = AVCaptureSession()
session?.beginConfiguration()
session?.sessionPreset = TGPhotoPickerConfig.shared.sessionPreset
if session!.canAddInput(input) {
session!.addInput(input)
}
if session!.canAddOutput(imageOutput) {
session!.addOutput(imageOutput)
}
previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer?.frame = view.bounds
previewLayer?.videoGravity = TGPhotoPickerConfig.shared.videoGravity
view.layer.addSublayer(previewLayer!)
session?.commitConfiguration()
session?.startRunning()
}
private func cameraWithPosistion(_ position: AVCaptureDevicePosition) -> AVCaptureDevice {
let type = AVCaptureDeviceType(rawValue: TGPhotoPickerConfig.shared.captureDeviceType.rawValue)
return AVCaptureDevice.defaultDevice(withDeviceType: type, mediaType: AVMediaTypeVideo, position: position)
}
private func setupUI() {
let takeButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH, height: TGPhotoPickerConfig.shared.takeWH))
takeButton.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height - TGPhotoPickerConfig.shared.buttonEdge.bottom)
takeButton.setImage(UIImage.size(width: TGPhotoPickerConfig.shared.takeWH, height: TGPhotoPickerConfig.shared.takeWH).border(width: 3).border(color: .white).color(.clear).corner(radius: TGPhotoPickerConfig.shared.takeWH / 2).image +
UIImage.size(width: TGPhotoPickerConfig.shared.takeWH - 10, height: TGPhotoPickerConfig.shared.takeWH - 10).color(UIColor(white: 0.95, alpha: 1) ).corner(radius: (TGPhotoPickerConfig.shared.takeWH - 10) / 2).image, for: .normal)
takeButton.setImage(UIImage.size(width: TGPhotoPickerConfig.shared.takeWH, height: TGPhotoPickerConfig.shared.takeWH).border(width: 3).border(color: .white).color(.clear).corner(radius: TGPhotoPickerConfig.shared.takeWH / 2).image +
UIImage.size(width: TGPhotoPickerConfig.shared.takeWH - 10, height: TGPhotoPickerConfig.shared.takeWH - 10).color(UIColor(white: 0.8, alpha: 1) ).corner(radius: (TGPhotoPickerConfig.shared.takeWH - 10) / 2).image, for: .highlighted)
takeButton.addTarget(self, action: #selector(takePhotoAction), for: .touchUpInside)
view.addSubview(takeButton)
let cameraChangeButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.6, height: TGPhotoPickerConfig.shared.takeWH * 0.6))
cameraChangeButton.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("camera"), for: .normal)
cameraChangeButton.center = CGPoint(x: UIScreen.main.bounds.width - TGPhotoPickerConfig.shared.buttonEdge.right, y: takeButton.center.y)
cameraChangeButton.addTarget(self, action: #selector(changeCameraPositionAction), for: .touchUpInside)
cameraChangeButton.contentMode = .scaleAspectFit
view.addSubview(cameraChangeButton)
let flashChangeButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.5, height: TGPhotoPickerConfig.shared.takeWH * 0.5))
flashChangeButton.center = CGPoint(x: cameraChangeButton.center.x, y: TGPhotoPickerConfig.shared.buttonEdge.top)
flashChangeButton.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flashauto"), for: .normal)
flashChangeButton.addTarget(self, action: #selector(flashChangeAction), for: .touchUpInside)
flashChangeButton.contentMode = .scaleAspectFit
flashButton = flashChangeButton
view.addSubview(flashChangeButton)
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.4, height: TGPhotoPickerConfig.shared.takeWH * 0.4))
backButton.center = CGPoint(x: TGPhotoPickerConfig.shared.buttonEdge.left , y: flashChangeButton.center.y)
backButton.setImage(UIImage.size(width: TGPhotoPickerConfig.shared.takeWH * 0.4, height: TGPhotoPickerConfig.shared.takeWH * 0.4)
.corner(radius: TGPhotoPickerConfig.shared.takeWH * 0.2)
.color(.clear)
.border(color: UIColor.white.withAlphaComponent(0.7))
.border(width: TGPhotoPickerConfig.shared.isShowBorder ? TGPhotoPickerConfig.shared.checkboxLineW : 0)
.image
.with({ context in
context.setLineCap(.round)
UIColor.white.setStroke()
context.setLineWidth(TGPhotoPickerConfig.shared.checkboxLineW)
let WH = TGPhotoPickerConfig.shared.takeWH * 0.4
context.move(to: CGPoint(x: WH * 0.6, y: WH * 0.2))
context.addLine(to: CGPoint(x: WH * 0.35, y: WH * 0.5))
context.move(to: CGPoint(x: WH * 0.35, y: WH * 0.5))
context.addLine(to: CGPoint(x: WH * 0.6, y: WH * 0.8))
context.strokePath()
}), for: .normal)
backButton.contentMode = .scaleAspectFit
backButton.addTarget(self, action: #selector(backAction), for: .touchUpInside)
view.addSubview(backButton)
showImageContainerView = UIView(frame: view.bounds)
showImageContainerView?.backgroundColor = TGPhotoPickerConfig.shared.previewBGColor
view.addSubview(showImageContainerView!)
let height = showImageContainerView!.bounds.height - TGPhotoPickerConfig.shared.takeWH - TGPhotoPickerConfig.shared.buttonEdge.bottom - TGPhotoPickerConfig.shared.previewPadding * 2
showImageView = UIImageView(frame: CGRect(x: TGPhotoPickerConfig.shared.previewPadding, y: TGPhotoPickerConfig.shared.previewPadding * 2, width: showImageContainerView!.bounds.width - 2 * TGPhotoPickerConfig.shared.previewPadding, height: height))
showImageView?.contentMode = .scaleAspectFit
showImageContainerView?.addSubview(showImageView!)
showImageContainerView?.isHidden = true
let giveupButton = createImageOperatorButton(nil, CGPoint(x: TGPhotoPickerConfig.shared.takeWH * 1.5, y: showImageContainerView!.bounds.height - TGPhotoPickerConfig.shared.takeWH * 1.5), TGPhotoPickerConfig.shared.getCheckboxImage(true, true, .circle, TGPhotoPickerConfig.shared.takeWH * 0.7).unselect)
giveupButton.addTarget(self, action: #selector(giveupImageAction), for: .touchUpInside)
showImageContainerView?.addSubview(giveupButton)
let ensureButton = createImageOperatorButton(nil, CGPoint(x: showImageContainerView!.bounds.width - TGPhotoPickerConfig.shared.takeWH * 1.5, y: showImageContainerView!.bounds.height - TGPhotoPickerConfig.shared.takeWH * 1.5), TGPhotoPickerConfig.shared.getCheckboxImage(true, false, .circle, TGPhotoPickerConfig.shared.takeWH * 0.7).select)
ensureButton.addTarget(self, action: #selector(useImageAction), for: .touchUpInside)
showImageContainerView?.addSubview(ensureButton)
}
private func createImageOperatorButton(_ title: String?, _ center: CGPoint, _ img: UIImage?) -> UIButton {
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.7, height: TGPhotoPickerConfig.shared.takeWH * 0.7))
btn.center = center
btn.setTitle(title, for: .normal)
btn.setImage(img, for: .normal)
btn.contentMode = .scaleAspectFit
return btn
}
@objc private func flashChangeAction() {
switch flashMode {
case .auto:
flashMode = .on
flashButton?.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flash"), for: .normal)
case .on:
flashMode = .off
flashButton?.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flashno"), for: .normal)
case .off:
flashMode = .auto
flashButton?.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flashauto"), for: .normal)
}
}
@objc private func backAction() {
dismiss(animated: true, completion: nil)
}
@objc private func takePhotoAction() {
let connection = imageOutput?.connection(withMediaType: AVMediaTypeVideo)
guard connection != nil else {
return
}
let photoSettings = AVCapturePhotoSettings()
photoSettings.flashMode = flashMode
imageOutput?.capturePhoto(with: photoSettings, delegate: self)
}
@objc private func changeCameraPositionAction() {
let animation = CATransition()
animation.duration = 0.5
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.type = TGPhotoPickerConfig.shared.transitionType
let newDevice: AVCaptureDevice!
let newInput: AVCaptureDeviceInput?
let position = input?.device.position
if position == .front {
newDevice = cameraWithPosistion(.back)
animation.subtype = kCATransitionFromLeft
} else {
newDevice = cameraWithPosistion(.front)
animation.subtype = kCATransitionFromRight
}
newInput = try? AVCaptureDeviceInput(device: newDevice)
guard newInput != nil else{
return
}
previewLayer?.add(animation, forKey: nil)
session?.beginConfiguration()
session?.removeInput(input)
if session!.canAddInput(newInput) {
session?.addInput(newInput!)
input = newInput
} else {
session?.addInput(input)
}
session?.commitConfiguration()
}
@objc private func giveupImageAction() {
showImageView?.image = UIImage()
showImageContainerView?.isHidden = true
}
@objc private func useImageAction() {
callbackPicutureData?(picData)
dismiss(animated: true, completion: nil)
}
}
@available(iOS 10.0, *)
extension TGCameraVC: AVCapturePhotoCaptureDelegate {
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
if error != nil {
print("error = \(String(describing: error?.localizedDescription))")
} else {
if let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer){
picData = imageData
showImageContainerView?.isHidden = false
showImageView?.image = UIImage(data: imageData)
if TGPhotoPickerConfig.shared.saveImageToPhotoAlbum{
self.saveImageToPhotoAlbum(UIImage(data: imageData)!)
}
}
}
}
fileprivate func saveImageToPhotoAlbum(_ savedImage:UIImage){
UIImageWriteToSavedPhotosAlbum(savedImage, self, #selector(imageDidFinishSavingWithErrorContextInfo), nil)
}
@objc fileprivate func imageDidFinishSavingWithErrorContextInfo(image:UIImage,error:NSError?,contextInfo:UnsafeMutableRawPointer?){
if canUseAlbum(){
let msg = (error != nil) ? TGPhotoPickerConfig.shared.saveImageFailTip : TGPhotoPickerConfig.shared.saveImageSuccessTip
let alert = UIAlertView(title: TGPhotoPickerConfig.shared.saveImageTip, message: msg, delegate: self, cancelButtonTitle: TGPhotoPickerConfig.shared.confirmTitle)
alert.show()
}
}
fileprivate func canUseAlbum()-> Bool{
if PHPhotoLibrary.authorizationStatus() != PHAuthorizationStatus.authorized {
let alertView = UIAlertView(title: TGPhotoPickerConfig.shared.PhotoLibraryUsage, message: TGPhotoPickerConfig.shared.PhotoLibraryUsageTip, delegate: nil, cancelButtonTitle: TGPhotoPickerConfig.shared.confirmTitle, otherButtonTitles: TGPhotoPickerConfig.shared.cancelTitle)
alertView.tag = TGPhotoPickerConfig.shared.alertViewTag
alertView.show()
return false
}else{
return true
}
}
}
效果如下
完整使用DEMO见:点击打开链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程学习网。
沃梦达教程
本文标题为:iOS 10自定义相机功能
基础教程推荐
猜你喜欢
- iOS中如何判断当前网络环境是2G/3G/4G/5G/WiFi 2023-06-18
- IOS获取系统相册中照片的示例代码 2023-01-03
- Android实现短信验证码输入框 2023-04-29
- iOS开发 全机型适配解决方法 2023-01-14
- Flutter进阶之实现动画效果(三) 2022-10-28
- MVVMLight项目Model View结构及全局视图模型注入器 2023-05-07
- iOS Crash常规跟踪方法及Bugly集成运用详细介绍 2023-01-18
- Android Compose自定义TextField实现自定义的输入框 2023-05-13
- iOS开发使用XML解析网络数据 2022-11-12
- Android开发Compose集成高德地图实例 2023-06-15