GPUImage简介
GPUImage 是一个基于 GPU 图像和视频处理的开源 iOS 框架。由于使用 GPU 来处理图像和视频,所以速度非常快,它的作者 BradLarson 称在 iPhone4 上其处理速度是使用 CPU 来处理的 100 倍 (CoreImage 也能使用 GPU 来处理图像,但我觉得 CoreImage 还是慢)。除了速度上的优势,GPUImage 还提供了很多很棒的图像处理滤镜,但有时候这些基本功能仍然无法满足实际开发中的需求,不用担心 GPUImage 支持自定义滤镜。
安装GPUImage
- 把GPUImage.xcodeproj 拖到你的Xcode project
- 在app的target依赖设置里面添加GPUImage作为Target Dependency
- 在build phase的Link Binary With Libraries, 把libGPUImage.a加进来.
- 添加下面这些系统framework:
CoreMedia
CoreVideo
OpenGLES
AVFoundation
QuartzCore - 头文件搜索路径: project’s build settings, 把GPUImage的source和source下的iOS目录加到搜索路径里, 使用相对路径和递归.
- 包含下面这个头文件:
1 | #import "GPUImage.h" |
GPUImage的简单使用
GPUImage中的有几个概念
⁃ output,输出源
⁃ intput,输入源
⁃ filter,滤镜
所以一个完整的滤镜处理流程是: output+X+input,X就是滤镜组(1+个滤镜)。GPUImage为了方便,新版本中提供了GPUImageFilterPipeline 这个东西,方便用户使用多个滤镜组合,不用担心前后的链式逻辑。
输入源是一些GPUImageOutput的子类.包括:
(1). GPUImageVideoCamera (for live video from an iOS camera)
(2.) GPUImageStillCamera (for taking photos with the camera)
(3). GPUImagePicture (for still images)
(4). GPUImageMovie (for movies). S
输出源可以是GPUImageView, 或者GPUImageMovieWriter
一个典型的例子
- GPUImageVideoCamera -> GPUImageSepiaFilter -> GPUImageView
处理流程
在使用GPUImage之前先做些准备工作。OpenGL ES程序来处理图片,会有以下几个步骤:
1、初始化OpenGL ES环境,编译、链接顶点着色器和片元着色器;
2、缓存顶点、纹理坐标数据,传送图像数据到GPU;
3、绘制图元到特定的帧缓存;
4、在帧缓存取出绘制的图像。
GPUImage里面有两个非常重要的类:
1 GPUImageFilter负责的是第一、二、三步。
2 GPUImageFramebuffer负责是第四步。
核心代码
将GPUImageView设置为self.view,根据face.png,设置GPUImagePicture,然后添加GPUImageTiltShiftFilter到响应链,再把GPUImageView作为响应链的终点,最后调用processImage,开始处理图像。1
2
3
4
5
6
7
8
9
10GPUImageView *primaryView = [[GPUImageView alloc] initWithFrame:self.view.frame];
self.view = primaryView;
UIImage *inputImage = [UIImage imageNamed:@"face.png"];
_sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage];
_sepiaFilter = [[GPUImageTiltShiftFilter alloc] init];
_sepiaFilter.blurRadiusInPixels = 40.0;
[_sepiaFilter forceProcessingAtSize:primaryView.sizeInPixels];
[_sourcePicture addTarget:_sepiaFilter];
[_sepiaFilter addTarget:primaryView];
[_sourcePicture processImage];
使用GPUImage自带的滤镜是远远不能满足需求的,下一篇就要看一下自定义滤镜。
遇到的问题
项目里,发现滤镜模块调用完了以后,内存上去了下不来,反复检查,所有GPUImage相关元素都已经释放了。后来想到了显存,arc环境下,只负责回收oc对象的内存,显存自然需要GPUImage使用者自己来回收,这样也就容易了,翻GPUImage的api,知道
GPUImageContext中有个framebufferCache:
1 | [[GPUImageContextsharedImageProcessingContext].framebufferCachepurgeAllUnassignedFramebuffers] |