关于GPUImage

这里直接引用官方描述:
The GPUImage framework is a BSD-licensed iOS library that lets you apply GPU-accelerated filters and other effects to images, live camera video, and movies. In comparison to Core Image (part of iOS 5.0), GPUImage allows you to write your own custom filters, supports deployment to iOS 4.0, and has a simpler interface. However, it currently lacks some of the more advanced features of Core Image, such as facial detection.
项目地址:https://github.com/BradLarson/GPUImage

滤镜基本原理

滤镜处理的原理就是把静态图片或者视频的每一帧进行图形变换再显示出来。它的本质就是像素点的坐标和颜色变化,这点从GPUImage项目中滤镜的源代码就可以了解到。
例如下面就是一个名为DarkenBlend的滤镜代码:

NSString *const kGPUImageDarkenBlendFragmentShaderString = SHADER_STRING( varying highp vec2 textureCoordinate; varying highp vec2 textureCoordinate2;

uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;

void main()
{

lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0);

}
);

GPUImage的最新版本已经内置了125个滤镜。也支持编写自定义滤镜(custom filter)。

图像处理流程

数据源需要实现GPUImageOutput接口,而后续各个环节(包括最后处理输出结果)的对象都要实现GPUImageInput接口。每个处理环节都是从上一个环节获取图像数据,进行处理后再将结果传递给下一个。下游的处理对象称为上一步的target。使用addTarget:方法为处理链路添加每个环节的对象。一个常见的链条如下:
数据源(例如GPUImageVideoCamera或者GPUImageMovie)->各类filter->GPUImageView
如果需要将结果输出到文件,只要把上述流程中最末的GPUImageView改为一个GPUImageMovieWriter即可。所以滤镜的添加和替换,以及输出结果都十分简单方便。

附一张GPUImage的结构图

接入app

将滤镜接入app非常简单,只要创建一个GPUImageMovie,一个具体的GPUImageFilter和一个用来显示的GPUImageView,然后按处理链条的上下游关系把它们用addTarget串起来。
下面附上我的app里面的调用代码(预览视频):

_movie = [[GPUImageMovie alloc] initWithURL:url];
_movie.shouldRepeat = YES;
_movie.playAtActualSpeed = YES;
_movie.playSound = YES;
_movie.delegate = self;GPUImageMissEtikateFilter *filter = [[GPUImageMissEtikateFilter alloc] init];//胶片效果
[_movie addTarget:filter];
[filter addTarget:self.gpuImageView];[_movie startProcessing];

然后就是一些重要的参数设置:
playAtActualSpeed
控制GPUImageView预览视频时的速度是否要保持真实的速度。如果设为NO,则会将视频的所有帧无间隔渲染,导致速度非常快。设为YES,则会根据视频本身时长计算出每帧的时间间隔,然后每渲染一帧,就sleep一个时间间隔,从而达到正常的播放速度。

shouldRepeat
控制视频是否循环播放。

当你不想预览,而是想将处理过的结果输出到文件时,步骤也类似,只是不再需要创建GPUImageView,而是需要一个GPUImageMovieWriter:

_writer = [[GPUImageMovieWriter alloc] initWithMovieURL:filtedMovieURL size:CGSizeMake(480, 640) fileType:(NSString *)kUTTypeMPEG4 outputSettings:outputSettings];
_writer.encodingLiveVideo = NO;
_writer.shouldPassthroughAudio = NO;
_movie.audioEncodingTarget = _writer;
_movie.playAtActualSpeed = NO;
[_movie addTarget:_curFilter];
[_curFilter addTarget:_writer];
[_movie enableSynchronizedEncodingUsingMovieWriter:_writer];
[_writer startRecording];
[_movie startProcessing];

一些局限和踩过的坑

1.预览时不支持播放声音
视频结果输出到GPUImageView预览时不支持播放声音,所以要自行添加声音播放:
自行创建了一个播放器对象

(void) setupSound
{
if (theAudioPlayer != nil)
{

[theAudioPlayer pause];
[theAudioPlayer seekToTime:kCMTimeZero];
theAudioPlayer = nil;

}
theAudioPlayer = [[AVPlayer alloc] initWithURL:self.url];
}

跟GPUImageView的图像同步播放

if (self.playSound && hasAudioTrack)
{[theAudioPlayer seekToTime:kCMTimeZero];[theAudioPlayer play];
}

由于GPUImageMovie里面没有在这几个重要位置提供回调,所以只能在源代码中直接添加,这也导致了对源码的侵入,不利于以后版本升级。

2.GPUImageView预览视频并循环播放时,当播放重新开始时,有大约50%的概率会有红屏闪一下,目前还未定位到原因

3.GPUImageView预览视频时,app切到后台会crash,所以要特别处理下,在willDisappear和handleApplicationWillEnterBackgroundNotify这两个时机都要暂停滤镜处理:

if (_movie) {[_movie endProcessing];[_movie removeAllTargets];_movie = nil;
}

对应的,在willAppear和handleApplicationWillEnterForegroundNotify这两个时机要重启处理:

if (!_movie) {_movie = [[GPUImageMovie alloc] initWithURL:url];
}_movie.shouldRepeat = YES;
_movie.playAtActualSpeed = YES;
_movie.playSound = YES;
_movie.delegate = self;[_movie addTarget:_curFilter];
[_curFilter addTarget:self.gpuImageView];[_movie startProcessing];

使用GPUImage实现视频滤镜相关推荐

  1. ffmpeg 将拆分的数据合成一帧_FFmpeg + OpenGLES 实现视频解码播放和视频滤镜

    FFmpeg 开发系列连载: FFmpeg 开发(01):FFmpeg 编译和集成 FFmpeg 开发(02):FFmpeg + ANativeWindow 实现视频解码播放 FFmpeg 开发(03 ...

  2. FFmpeg源码分析:视频滤镜介绍(上)

    FFmpeg在libavfilter模块提供音视频滤镜.所有的视频滤镜都注册在libavfilter/allfilters.c.我们也可以使用ffmpeg -filters命令行来查看当前支持的所有滤 ...

  3. Premiere Pro 2.0 添加视频滤镜

    9. 添加视频滤镜 Premiere Pro 2.0的视频特效与Photoshop中的滤镜很类似,而且由于视频的特点,这些效果都是随着时间动态变化的.Premiere Pro 2.0中的视频滤镜效果包 ...

  4. fcpx插件:38项视频滤镜Yanobox Moods

    今天小编带给大家认识的FCPX插件是:Yanobox Moods 共38种视频滤镜,它可以放到标题,图像,视频和生成器上,可以在屏幕上或屏幕外进行视频特效制作,它有用直观,易于使用的平视显示界面,实现 ...

  5. FFMPEG视频滤镜(一)

    前言 介绍FFmpeg中旋转rotate.拼接hstack.翻转hflip.边缘edgedetect视频滤镜的使用方法. 1. 旋转滤镜 1.1 名称:rotate 1.2 语法:-angle:旋转角 ...

  6. EDIUS视频滤镜中的模糊特效该如何制作

    小编今天又给学习EDIUS视频编辑软件的小伙伴带来福利啦,快点猜猜是什么?嘿嘿,相信常来光顾我文章的同学肯定能猜到,那就是我又为你们带来了EDIUS教程文章了.有木有很开心呢?反正小编我每天只要能帮助 ...

  7. 录制你的动态美——Java的视频滤镜

    众所周知视频是不能P的,所以一旦学会了视频滤镜,你就是最靓的仔! 创建一个滤镜类: 其实具体思路与之前的图片滤镜极为相似,故我直接将代码贴出来. public BufferedImage grayim ...

  8. FFmpeg进阶:视频滤镜大全

    在做视频特效的时候,很多特效其实不用自己写,FFmpeg的视频滤镜里面提供了很丰富的滤镜特效.这里翻译了一下FFmpeg官方文档的所有视频滤镜的介绍,供大家参考.由于很多地方概念比较生疏,翻译的可能不 ...

  9. 视频滤镜软件哪个好?推荐几个视频滤镜软件给你

    这天周末,连续加班工作的我们终于迎来了小假期,于是便打算去游玩放松下,有个朋友还准备了相机打算拍摄vlog记录下. 游玩回来后,她便兴致高昂的挑选照片制作视频.但一番折腾后,她有些垂头丧气的对我说,不 ...

最新文章

  1. unix awk手册读书笔记
  2. Syszuxpin中文输入法移植
  3. 关于以追加模式写入文件时,为什么第一行是空行?
  4. ASP.NET MVC+LINQ开发一个图书销售站点(9):编辑目录
  5. MySQL+Tomcat+JVM,看完还怕面试官
  6. rcp rapido_Rapido使用数据改善乘车调度
  7. Python学习笔记:字典(dict)
  8. django 1.8 官方文档翻译: 2-5-1 管理器 (初稿)
  9. java过滤器解决乱码_[java]如何使用过滤器解决jsp乱码
  10. CMU 15-213 Introduction to Computer Systems学习笔记(15)System-Level I/O
  11. WYSE S10、WYSE V90、HP T5740瘦客机评测
  12. 动力下肢矫形器和外骨骼辅助策略综述
  13. 【语音识别】基于动态时间规整(DTW)的孤立字语音识别Matlab源码
  14. 手机端h5唤起苹果地图
  15. 只有迷信的人,没有迷信的知识
  16. opencv inrange函数
  17. java一维数组正序输出,java将一个数组逆序输出-java将一个数组逆序输出的方法-吾爱编程网...
  18. RHCSA之账户与安全_创建账户与组(useradd.groupadd.id)
  19. C#实现气泡屏保效果(用1个timer)
  20. 一、数组操作的基本函数

热门文章

  1. NIPS 2016 Highlighted Papers
  2. vue-cli中的webpack的config配置详细说明
  3. django配置templates、static、media和连接mysql数据库
  4. MySQL中事物的详解
  5. Date扩展 正则匹配
  6. union 和 union all 有什么不同?
  7. Fifth scrum meeting - 2015/10/30
  8. window.parent和window.opener区别
  9. 面向对象JS编程(一)——创建对象
  10. IDEA写vue项目出现红色波浪线警告如何解决??