Swift 学习笔记(九)
2019-03-01
终于把视频流的图片取出来了
先构建session设置输入输出
override func viewDidLoad() {
super.viewDidLoad()
let session = AVCaptureSession() //创建会话
let device = AVCaptureDevice.default(_:.builtInWideAngleCamera, for: .video, position: .back) //选择设备
//设置输入
do {
let videoInput = try AVCaptureDeviceInput(device: device!)
session.addInput(videoInput)
} catch {
print("error")
return
}
//设置输出
let videoOutput = AVCaptureVideoDataOutput() //相当于截获输出🔴可以访问帧
//这里设置了回调队列才可以让下面的captureOutput函数能够同时运行
let myQueue = DispatchQueue(label: "myQueue")//设置队列
videoOutput.setSampleBufferDelegate(self, queue: myQueue)//回调
session.addOutput(videoOutput)
//对于UIView控件要设置预览层//相当于图层. 可以多个图层叠加
let ViewLayer = AVCaptureVideoPreviewLayer(session: session) //设置预览层
ViewLayer.frame = myView!.bounds
myView?.layer.addSublayer(ViewLayer)
self.mySession = session //会话传到外部变量中
}
@IBOutlet weak var myView2: UIImageView!
@IBOutlet weak var myView: UIView? //视窗
//按钮
@IBAction func myButton(_ sender: Any) {
self.mySession!.startRunning()
}
@IBAction func myBt2(_ sender: Any) {
self.mySession!.stopRunning()
}
//这个函数会在俘获到每一帧运行. sampleBuffer参数就是多媒体缓存
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
//取出图片缓存
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { print("提取图片失败")
return }
let image: UIImage = self.convert(pixelBuffer: pixelBuffer) //CVImageBuffer转换成UIImage
//设置图片角度
let jiaodu = image.imageOrientation.rawValue + 3
let okimage = UIImage(cgImage: image.cgImage!, scale: image.scale, orientation:UIImage.Orientation(rawValue: jiaodu)!)
DispatchQueue.main.sync {
//这里是UIImageView控件, 只能放一张图//不存在多图层//要想在图上画画必须重新绘制图片
self.myView2.image = okimage //更新UI
}
}
//CVImageBuffer->CIImage->CGImage->UIImage
func convert(pixelBuffer:CVImageBuffer) -> UIImage
{
let ciimage: CIImage = CIImage(cvImageBuffer: pixelBuffer)
let context:CIContext = CIContext.init(options: nil)
let cgImage:CGImage = context.createCGImage(ciimage, from: ciimage.extent)!
let image:UIImage = UIImage.init(cgImage: cgImage)
return image
}
}
////readLine()读取用户输入 返回可选类型