iOS 10自定義相機功能
更新時間:2019年04月21日 12:03:37 作者:cloudtarget
這篇文章主要為大家詳細介紹了iOS 10自定義相機功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了iOS 10自定義相機功能的具體代碼,供大家參考,具體內(nèi)容如下
直接上代碼
// // 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見:點擊打開鏈接
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用Xcode為iOS應(yīng)用項目創(chuàng)建PCH文件的方法及應(yīng)用示例
這篇文章主要介紹了使用Xcode為iOS應(yīng)用項目創(chuàng)建PCH文件的方法及應(yīng)用示例,PCH文件可以保留應(yīng)用的很多的基礎(chǔ)設(shè)置信息以供復(fù)用,需要的朋友可以參考下2016-03-03iOS中wkwebView內(nèi)存泄漏與循環(huán)引用問題詳解
這篇文章主要給大家介紹了關(guān)于iOS中wkwebView內(nèi)存泄漏與循環(huán)引用問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07IOS 開發(fā)之自定義按鈕實現(xiàn)文字圖片位置隨意定制
這篇文章主要介紹了IOS 開發(fā)之自定義按鈕實現(xiàn)文字圖片位置隨意定制的相關(guān)資料,這里附有實例代碼及實現(xiàn)效果圖,需要的朋友可以參考下2016-12-12iOS動畫解析之圓球加載動畫XLBallLoading的實現(xiàn)
加載動畫對大家來說都不陌生,我們在平時都會遇見,開發(fā)中也必不可少,所以下面這篇文章主要給大家介紹了關(guān)于iOS動畫解析之圓球加載動畫XLBallLoading實現(xiàn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。2017-11-11iOS安全防護系列之字符串及系統(tǒng)函數(shù)隱藏詳解
這篇文章主要給大家介紹了關(guān)于iOS安全防護系列之字符串及系統(tǒng)函數(shù)隱藏的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07iOS中使用NSURLConnection處理HTTP同步與異步請求
NSURLConnection的作用現(xiàn)在已經(jīng)基本被NSURLSession所取代,所以我們簡單了解下iOS中使用NSURLConnection處理HTTP同步與異步請求的方法即可:2016-07-07