iOS GPUImage研究五:短视频拍摄(滤镜、文件写入)
2017-04-16 21:42
716 查看
希望这个Demo,可以给大家在视频滤镜制作上带来一些灵感、避免重复造轮子。也希望大家转载的时候带上原文地址,算是对原创的鼓励。
最下方有Demo地址
运行环境Xcode7.3.1
这个Demo应该是对GPUImage的总结吧,包含了视频写入,滤镜信息读取。前面几篇文章也分别对GPUImage中常用的功能进行了分别介绍。虽说GPUImage是开源的,但对初学者来讲上手还是有一定难度的,希望可以帮助大家。
在GPUImage的探索的道路上依旧还未停止。
需求:
效果如图 :
![这里写图片描述]
Demo目录:
可通过调节0 * (1 - fabs(scaleForDistance));来改变效果。
storyboard具备快速开发的优点,除了实时变化相对于代码差一点,其他的他已经很成熟、也是伟大的开发模式、在这里也希望那些老家伙们别固执与代码布局,紧随时代吧!
特别提示:注意Mylayout的位置 很重要
初始化相机和GPUImageview:
初始化写入对象:
切换滤镜
播放视频
保存到相册:
用到的全局方法:
模糊效果:
最下方有Demo地址
运行环境Xcode7.3.1
这个Demo应该是对GPUImage的总结吧,包含了视频写入,滤镜信息读取。前面几篇文章也分别对GPUImage中常用的功能进行了分别介绍。虽说GPUImage是开源的,但对初学者来讲上手还是有一定难度的,希望可以帮助大家。
在GPUImage的探索的道路上依旧还未停止。
需求:
序号 | 描述 |
---|---|
1. | 实现画面获取:使用GPUImageMovieCamera |
2. | 实现画面呈现:使用GPUImageView |
3. | 实现美颜滤镜:包含读取图像颜色矩阵,以及GPUImage自带滤镜组合和网上流传的美颜滤镜 |
4. | 实现实时滤镜视频处理:使用GPUImageMovieWriter |
5. | 实现保存到相册,并播放。 |
6. | 简单地切换动画,让过程看起来更自然。 |
![这里写图片描述]
Demo目录:
相关类 | 说明: |
---|---|
Frameworks | 是使用GPUImage的必须依赖库。 |
GPUImageCustom 4000 LookupFilter | 是将读取图片信息并将之转化为滤镜 的关键类。也包含一些我自己的滤镜组合,包含鱼眼滤镜、水晶球滤镜、放行滤镜、浮雕、反鱼眼等。 |
FSKVideoFilterVc | 是主控制器,包含切换摄像头、视频滤镜写入、视频录制播放、保存相册、切换滤镜、以及组合滤镜的使用方法。 |
SkVideoFilterView | 是滤镜的视图,继承collectionview,一共包含大概30种组合滤镜。 |
FilterModel | 是滤镜Model,处理滤镜名称定义,以及滤镜列表的初始化。 |
SSGPUImageBeautyFilter | 就是GPUImageBeautifulFilter,只是换了个名字而已。 |
MyLayout | 是一个继承UICollectionViewFlowLayout的布局类,一个是拥有缩放效果的布局方式,后来我把缩放效果调成了0,因为综合效果的原因。 |
CGFloat distance = offset - attribute.center.x; // 越往中心移动,值越小,那么缩放就越小,从而显示就越大 // 同样,超过中心后,越往左、右走,缩放就越大,显示就越小 CGFloat scaleForDistance = distance / self.itemSize.height; // 可调整,值越大,显示就越大 CGFloat scaleForCell = 1 + 0 * (1 - fabs(scaleForDistance)); // only scale y-axis attribute.transform3D = CATransform3DMakeScale(1, scaleForCell, 1); attribute.zIndex = 1;
可通过调节0 * (1 - fabs(scaleForDistance));来改变效果。
StoryBoard说明:
storyboard具备快速开发的优点,除了实时变化相对于代码差一点,其他的他已经很成熟、也是伟大的开发模式、在这里也希望那些老家伙们别固执与代码布局,紧随时代吧!
特别提示:注意Mylayout的位置 很重要
初始化相机和GPUImageview:
func setNewCameraAndGPUViewAndStart() { videoCamera = GPUImageVideoCamera.init(sessionPreset: AVCaptureSessionPreset640x480, cameraPosition: AVCaptureDevicePosition.Front) videoCamera.outputImageOrientation = UIInterfaceOrientation.Portrait videoCamera.horizontallyMirrorFrontFacingCamera = true videoCamera.horizontallyMirrorRearFacingCamera = true filter = SSGPUImageBeautyFilter.init() filterView = self.view as! GPUImageView filterView.fillMode = kGPUImageFillModePreserveAspectRatioAndFill videoCamera.addTarget(filter as GPUImageInput) filter.addTarget(filterView) videoCamera.startCameraCapture() }
初始化写入对象:
func getNewMovieWriter() { let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let documentsDirectory = paths[0] as String let filePath : String? = "\(documentsDirectory)/DBLiveTest\(currentTimeStamp()).mp4" movieURL = NSURL(fileURLWithPath: filePath!) movieWriter = GPUImageMovieWriter.init(movieURL: movieURL, size: CGSizeMake(480.0, 640.0)) movieWriter.encodingLiveVideo = true if groupFilter == nil { filter.addTarget(movieWriter) }else{ self.groupFilter?.addTarget(movieWriter) } videoCamera.audioEncodingTarget = movieWriter }
切换滤镜
//换滤镜 func switchFilter(index: Int) { self.filter?.removeAllTargets() self.groupFilter?.removeAllTargets() self.currentFilterIndex = index let lookupImageName = self.filterModel.filterList[index].lookupImageName self.lookupFilter = GPUImageCustomLookupFilter.init(lookupImageName: lookupImageName) self.setUpGroupFilters(self.lookupFilter!) self.groupFilter?.addTarget(filterView) self.groupFilter?.addTarget(movieWriter) } func setUpGroupFilters(lookupFilter: GPUImageCustomLookupFilter) { self.groupFilter = GPUImageFilterGroup.init() self.groupFilter?.addTarget(filter) self.filter?.addTarget(lookupFilter) self.groupFilter?.initialFilters = [self.filter!] self.groupFilter?.terminalFilter = lookupFilter }
播放视频
func playVideoAndAddPreView() { dispatch_async(dispatch_get_main_queue()) { let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true) let documentsDirectory = paths[0] as String let filePath1 : String? = "\(documentsDirectory)/DBLiveTest\(currentTimeStamp()).jpg"; UIImagePNGRepresentation(getFirstImageFromVideo(self.movieURL))?.writeToFile(filePath1!, atomically: true); self.thumbURL = NSURL(fileURLWithPath: filePath1!) animationFlipFromRight(self.filterView) self.videoCamera.stopCameraCapture() self.playerItem = AVPlayerItem(URL: self.movieURL) // 创建 AVPlayer 播放器 self.player = AVPlayer(playerItem: self.playerItem) // 将 AVPlayer 添加到 AVPlayerLayer 上 self.playerLayer = AVPlayerLayer(player: self.player) // 设置播放页面大小 self.playerLayer.frame = self.view.frame // 设置画面缩放模式 self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill // 在视图上添加播放器 self.view.layer.addSublayer(self.playerLayer) // 开始播放 self.player.play() self.addPreViewToSufureView() } }
保存到相册:
func doYouWantSaveItToAlbum(bool:Bool) { if bool == true { let library = ALAssetsLibrary() if library.videoAtPathIsCompatibleWithSavedPhotosAlbum(movieURL) { library.writeVideoAtPathToSavedPhotosAlbum(movieURL, completionBlock: { (assetURL, error) in dispatch_async(dispatch_get_main_queue(), { if error == nil{ let alert = UIAlertView.init(title: "提示消息", message: "保存成功", delegate: nil, cancelButtonTitle: "确定") alert.show() }else{ let alert = UIAlertView.init(title: "提示消息", message: "保存失败", delegate: nil, cancelButtonTitle: "确定") alert.show() } }) }) } } }
用到的全局方法:
//翻转动画 func animationFlipFromLeft(view:UIView) { UIView.beginAnimations(nil, context: nil) UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut) UIView.setAnimationDuration(0.5) UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromLeft, forView: view, cache: false) UIView.commitAnimations() } //翻转动画 func animationFlipFromRight(view:UIView) { UIView.beginAnimations(nil, context: nil) UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut) UIView.setAnimationDuration(0.5) UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromRight, forView: view, cache: false) UIView.commitAnimations() } //时间戳 func currentTimeStamp()->String { let now = NSDate() let dformatter = NSDateFormatter() dformatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss" print("当前日期时间:\(dformatter.stringFromDate(now))") //当前时间的时间戳 let timeInterval:NSTimeInterval = now.timeIntervalSince1970 let timeStamp = Int(timeInterval) return String(timeStamp) } //获取视频第一帧 func getFirstImageFromVideo(videoUrl:NSURL)->(UIImage){ let asset = AVURLAsset(URL:videoUrl) let generator = AVAssetImageGenerator(asset: asset) generator.appliesPreferredTrackTransform=true let time = CMTimeMakeWithSeconds(0.0,600) var actualTime:CMTime = CMTimeMake(0,0) var image:CGImageRef! do{ image = try generator.copyCGImageAtTime(time, actualTime: &actualTime) }catch let error as NSError{ print(error) } return UIImage(CGImage: image) }
模糊效果:
//添加模糊效果 func addVisualEffectView() { self.effectView = UIVisualEffectView.init(effect: UIBlurEffect.init(style: UIBlurEffectStyle.Light)); self.view.addSubview(self.effectView) self.effectView.frame = self.view.bounds }
Demo 地址:http://download.csdn.net/my
相关文章推荐
- iOS GPUImage研究四:为视频文件添加滤镜
- iOS GPUImage研究序一:内置滤镜
- ios GPUImage简单滤镜 -- 录制视频(保存+聚焦)
- iOS GPUImage研究序一:内置滤镜
- iOS GPUImage研究二:捕获图像stillCamera写入相册
- iOS GPUImage研究序一:内置滤镜
- iOS GPUImage研究六:为视频添加图片水印
- iOS上用GPUImage给视频加滤镜
- iOS GPUImage之GPUImageMovie视频滤镜(2)
- iOS GPUImage之GPUImageMovie视频滤镜(1)
- iOS上用GPUImage给视频加滤镜
- iOS 使用GPUImage为本地视频添加滤镜
- iOS GPUImage研究总结
- 使用GPUImage实现视频滤镜
- iOS GPUImage之自定义滤镜
- 使用GPUImage实现视频滤镜
- GPUImage之视频流滤镜
- 用GPUImage给视频添加多个滤镜
- 模仿Flickr 使用GPUImage的实时相机滤镜(iOS源代码)
- 使用GPUImage实现视频滤镜