iOS GPUImage音视频采集以及美颜功能

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!
    }()
    

创建camera以及滤镜组
    
    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)
            }
        }
        
    }

效果图如下:



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值