欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS 10自定义相机功能

程序员文章站 2023-11-30 08:04:28
本文实例为大家分享了ios 10自定义相机功能的具体代码,供大家参考,具体内容如下 直接上代码 // // tgcameravc.swift // tgph...

本文实例为大家分享了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
  }
 }
}

效果如下

iOS 10自定义相机功能

完整使用demo见:点击打开链接

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。