iOS GPUImage音视频采集以及美颜功能
GPUImageStillCamera:用于拍摄当前手机的画面, 并且保存图片
GPUImageVideoCamera:通常用于实时视频的录制
使用方法:GPUImageStillCamera \ GPUImageVideoCamera>GPUImageFilter->GPUImageView 摄像机转到滤镜再转到view上
本篇博客Demo:iOS GPUImage音视频采集以及美颜功能
初始化需要用到的属性
fileprivate lazy var camera: GPUImageVideoCamera? = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPresetHigh, cameraPosition: .front)
fileprivate lazy var preView: GPUImageView = {
let preView = GPUImageView(frame: self.view.bounds)
return preView
}()
let saturationFilter = GPUImageSaturationFilter() // 饱和
let bilateralFilter = GPUImageBilateralFilter() // 磨皮
let brightnessFilter = GPUImageBrightnessFilter() // 美白
let exposureFilter = GPUImageExposureFilter() // 曝光
fileprivate var player: AVPlayer?
fileprivate var isEndRecording = false
// 视频存放路径Url
var fileURL : URL {
return URL(fileURLWithPath: pathString)
}
//视频存放路径
var pathString: String {
return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/test.mp4"
}
// 创建写入对象
fileprivate lazy var movieWriter : GPUImageMovieWriter = { [weak self] in
if FileManager.default.fileExists(atPath: (self?.pathString)!) {
try? FileManager.default.removeItem(atPath: (self?.pathString)!)
}
let movieWriter = GPUImageMovieWriter(movieURL: self?.fileURL, size: (self?.view.bounds.size)!)
movieWriter?.encodingLiveVideo = true
return movieWriter!
}()
fileprivate func conifgCamera() {
//创建预览的View
view.insertSubview(preView, at: 0)
//设置camera方向
camera?.outputImageOrientation = .portrait
camera?.horizontallyMirrorFrontFacingCamera = true
///防止允许声音通过的情况下,避免录制第一帧黑屏闪屏
camera?.addAudioInputsAndOutputs()
//获取滤镜组
let filterGroup = getGroupFilters()
//设置默认值
bilateralFilter.distanceNormalizationFactor = 5.5
exposureFilter.exposure = 0
brightnessFilter.brightness = 0
saturationFilter.saturation = 1.0
//设置GPUImage的响应链
camera?.addTarget(filterGroup)
filterGroup.addTarget(preView)
//开始采集视频
camera?.startCapture()
// 将writer设置成滤镜的target
filterGroup.addTarget(movieWriter)
camera?.delegate = self
camera?.audioEncodingTarget = movieWriter
movieWriter.startRecording()
}
fileprivate func getGroupFilters() -> GPUImageFilterGroup {
//创建滤镜组
let filterGroup = GPUImageFilterGroup()
//创建滤镜(设置滤镜的引来关系)
bilateralFilter.addTarget(brightnessFilter)
brightnessFilter.addTarget(exposureFilter)
exposureFilter.addTarget(saturationFilter)
//设置滤镜起点 终点的filter
filterGroup.initialFilters = [bilateralFilter]
filterGroup.terminalFilter = saturationFilter
return filterGroup
}
//翻转
@objc fileprivate func pickUpCameraSelected() {
camera?.rotateCamera()
}
//滤镜
@objc fileprivate func filterCameraSelected() {
filterView.show()
}
//结束录制
@objc fileprivate func endRecordSelected() {
isEndRecording = true
preView.removeFromSuperview()
movieWriter.finishRecording()
let filterGroup = getGroupFilters()
filterGroup.removeTarget(movieWriter)
camera?.stopCapture()
}
//播放
@objc fileprivate func playRecordSelected() {
print(fileURL)
if !FileManager.default.fileExists(atPath: pathString) {
showAlert("播放路径不存在")
return
}
let playerItem = AVPlayerItem(url: fileURL)
player = AVPlayer(playerItem: playerItem)
let layer = AVPlayerLayer(player: player)
layer.frame = CGRect(x: (kWidth - 220)/2.0, y: 210, width: 220, height: 220)
view.layer.addSublayer(layer)
player?.play()
}
//拍照
@objc fileprivate func takePhotoSelected() {
guard let camera = camera else {
fatalError("请退出程序重新录制!")
}
if camera.isMember(of: GPUImageVideoCamera.self) {
showAlert("请查看takePhotoSelected方法的说明")
return
}
/*说明:
GPUImageVideoCamera:通常用于实时视频的录制
GPUImageStillCamera:用于拍摄当前手机的画面, 并且保存图片
1. 将
fileprivate lazy var camera: GPUImageVideoCamera? = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPresetHigh, cameraPosition: .front)
改为
fileprivate lazy var camera: GPUImageStillCamera? = GPUImageStillCamera(sessionPreset: AVCaptureSessionPresetHigh, cameraPosition: .front)
2. 取消以下注释
*/
/*
camera.capturePhotoAsImageProcessedUp(toFilter: getGroupFilters(), withCompletionHandler: {[weak self] (image, error) in
if error == nil {
UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
self?.showAlert("图片保存成功,请退出程序重新录制!")
}else{
self?.showAlert("图片保存失败,请退出程序重新录制!")
}
self?.endRecordSelected()
})
*/
}
美颜效果的切换处理,可以参考 iOS GPUImage图像处理
//根据滑动改变美颜效果
fileprivate func configSliderChange() {
filterView.sliderDidValueChanged = {[weak self] (_, slider, type) in
print(slider.value)
switch type {
case .bilateralFilter:
self?.bilateralFilter.distanceNormalizationFactor = 10.0 - CGFloat(slider.value)
break
case .exposureFilter:
self?.exposureFilter.exposure = CGFloat(slider.value) * 20.0 - 10.0
break
case .brightnessFilter:
self?.brightnessFilter.brightness = CGFloat(slider.value) * 2.0 - 1.0
break
case .saturationFilter:
self?.saturationFilter.saturation = CGFloat(slider.value) * 2.0
break
}
}
}
//开关美颜功能
fileprivate func configSwitchChange() {
filterView.switchDidValueChanged = {[weak self] (_, filterSwitch, isOpen) in
if isOpen {
self?.camera?.removeAllTargets()
let group = self?.getGroupFilters()
self?.camera?.addTarget(group)
group?.addTarget(self?.preView)
}else{
self?.camera?.removeAllTargets()
self?.camera?.addTarget(self?.preView)
}
}
}
效果图如下: