真的好久没写Blog了。。囧
捕捉硬件数据需要用到以下几个类
AVCaptureSessionAVCaptureDeviceinputAVCaptureVIDeoDataOutputAVCaptureVIDeoPrevIEwLayer
AVCaptureSession
控制着硬件的input以及数据的Output(就理解为控制器吧)
AVCaptureDeviceinput
硬件的输入(从AVCaptureDevice对象中捕捉输入相关得数据)
AVCaptureVIDeoDataOutput
视频数据的输出(AVCaptureOutput的子类,捕捉输出相关得属性)
AVCaptureVIDeoPrevIEwLayer
预览视图
说下大概得逻辑
初始化Session(负责协调输入,输出数据交互)
通过AVCaptureDevice.defaultDeviceWithMediaType方法来获取AVCaptureDevice(音频,视频) 具体看你传进去得参数而定
初始化输入,输出 对象
设置输出画质,将输入,输出 对象添加进session中
创建GCD并设置输出对象的相关回调
代码部分
检测摄像头权限是否可用以及跳转设置的函数
func checkVIDeoAuth()
func openSettings()这里的跳转设置函数是在IOS8以后才可使用的
摄像头输入输出设置的相关设置
func setupCamera()
完整代码如下
//// VIEwController.swift// CameraExample//// Created by Peter_Qin on 15/11/20.// copyright © 2015年 Chin_Hui. All rights reserved.//import UIKitimport AVFoundationclass VIEwController: UIVIEwController,AVCaptureVIDeoDataOutputSampleBufferDelegate,UIAlertVIEwDelegate { /// 摄像头授权状态 var cameraAuthStatus: AVAuthorizationStatus! /// 预览Layer var captureVIDeoPrevIEwLayer: AVCaptureVIDeoPrevIEwLayer! /// Session var session: AVCaptureSession! /// 硬件input var captureinput:AVCaptureDeviceinput! /// 数据Output var captureOutput:AVCaptureVIDeoDataOutput! var customimgVIEw: UIImageVIEw! /** 跳转至设置 */ func openSettings() { let settingsURL:NSURL = NSURL(string:UIApplicationopenSettingsURLString)! UIApplication.sharedApplication().openURL(settingsURL) } /** Check vIDeo authorization status */ func checkVIDeoAuth() { switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVIDeo) { case AVAuthorizationStatus.Authorized://已经授权 self.cameraAuthStatus = AVAuthorizationStatus.Authorized break case AVAuthorizationStatus.NotDetermined: AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVIDeo,completionHandler: { (granted: Bool) -> VoID in if(granted){ //受限制 self.cameraAuthStatus = AVAuthorizationStatus.Restricted exit(0) } }) break case AVAuthorizationStatus.DenIEd: AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVIDeo,completionHandler: { (granted: Bool) -> VoID in if(!granted){ //否认 self.cameraAuthStatus = AVAuthorizationStatus.DenIEd let warnMsg:UIAlertVIEw = UIAlertVIEw(Title: "提示",message: "摄像头权限未未开启,点击确认跳转至设置",delegate: self,cancelbuttonTitle: "确认") warnMsg.show() } }) break default: break } } /** 摄像头设置相关 By Hui */ func setupCamera() { self.session = AVCaptureSession() let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVIDeo)! self.captureOutput = AVCaptureVIDeoDataOutput() do{ try self.captureinput = AVCaptureDeviceinput(device: device) }catch let error as NSError{ print(error) } self.checkVIDeoAuth() self.session.beginConfiguration() //画面质量设置 self.session.sessionPreset = AVCaptureSessionPreset1920x1080 self.captureOutput.vIDeoSettings = [kCVPixelBufferPixelFormatTypeKey:NSNumber(unsignedInt: kCVPixelFormatType_32BGRA),kCVPixelBufferWIDthKey:NSNumber(integer: 1920),kCVPixelBufferHeightKey:NSNumber(integer: 1080)] if(self.session.canAddinput(self.captureinput)){ self.session.addinput(self.captureinput) } if(self.session.canAddOutput(self.captureOutput)){ self.session.addOutput(self.captureOutput) } let subQueue:dispatch_queue_t = dispatch_queue_create("subQueue",nil) captureOutput.setSampleBufferDelegate(self,queue: subQueue) //预览Layer设置 self.captureVIDeoPrevIEwLayer = AVCaptureVIDeoPrevIEwLayer(session: self.session) self.captureVIDeoPrevIEwLayer.frame = CGRectMake(self.vIEw.frame.size.wIDth/2 - (320/2),320,240) self.captureVIDeoPrevIEwLayer.vIDeoGravity = AVLayerVIDeoGravityResizeAspectFill self.vIEw.layer.addSublayer(self.captureVIDeoPrevIEwLayer) self.session.commitConfiguration() } overrIDe func vIEwDIDLoad() { super.vIEwDIDLoad() // Do any additional setup after loading the vIEw,typically from a nib. self.setupCamera() self.customimgVIEw = UIImageVIEw(frame: CGRectMake(self.captureVIDeoPrevIEwLayer.frame.origin.x,250,240)) self.vIEw.addSubvIEw(self.customimgVIEw) } overrIDe func vIEwWillAppear(animated: Bool) { super.vIEwWillAppear(animated) self.session.startRunning() } overrIDe func vIEwWilldisappear(animated: Bool) { self.session.stopRunning() super.vIEwWilldisappear(animated) } /** 数据流BufferRef转Image - parameter sampleBuffer: 数据流 - returns: UIImage */ func getimageData(sampleBuffer:CMSampleBuffer!)-> UIImage { let imageBuffer:CVImageBufferRef = CMSampleBufferGetimageBuffer(sampleBuffer)! CVPixelBufferLockBaseAddress(imageBuffer,0) let bytesPerRow:size_t = CVPixelBufferGetBytesPerRow(imageBuffer) let wIDth:size_t = CVPixelBufferGetWIDth(imageBuffer) let height:size_t = CVPixelBufferGetHeight(imageBuffer) let safepoint:UnsafeMutablePointer<VoID> = CVPixelBufferGetBaseAddress(imageBuffer) let bitMAPInfo:UInt32 = CGBitmAPInfo.ByteOrder32little.rawValue | CGImageAlphaInfo.PremultiplIEdFirst.rawValue //RGB let colorSpace: CGcolorSpaceRef = CGcolorSpaceCreateDeviceRGB()! let context:CGContextRef = CGBitmapContextCreate(safepoint,wIDth,height,8,bytesPerRow,colorSpace,bitMAPInfo)! let quartimage: CGImageRef = CGBitmapContextCreateImage(context)! CVPixelBufferUnlockBaseAddress(imageBuffer,0) return UIImage(CGImage: quartimage,scale: 1,orIEntation: UIImageOrIEntation.Right) } //AVCaptureVIDeoDataOutputSampleBufferDelegate func captureOutput(captureOutput: AVCaptureOutput!,dIDOutputSampleBuffer sampleBuffer: CMSampleBuffer!,fromConnection connection: AVCaptureConnection!){ let localimg = self.getimageData(sampleBuffer) //GCD 主线程队列中刷新UI dispatch_async(dispatch_get_main_queue()) { () -> VoID in self.customimgVIEw.image = localimg } } //UIAlertVIEwDelegate func alertVIEw(alertVIEw: UIAlertVIEw,clickedbuttonAtIndex buttonIndex: Int){ if(buttonIndex == 0){ self.openSettings() } } overrIDe func dIDReceiveMemoryWarning() { super.dIDReceiveMemoryWarning() // dispose of any resources that can be recreated. }}
Developer官网有个Example 叫 AVCam-iOS
总结以上是内存溢出为你收集整理的通过AVFoundation获取摄像头数据[Swift]全部内容,希望文章能够帮你解决通过AVFoundation获取摄像头数据[Swift]所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)