GPUImage(一)简介

GPUImage简介

GPUImage 是一个基于 GPU 图像和视频处理的开源 iOS 框架。由于使用 GPU 来处理图像和视频,所以速度非常快,它的作者 BradLarson 称在 iPhone4 上其处理速度是使用 CPU 来处理的 100 倍 (CoreImage 也能使用 GPU 来处理图像,但我觉得 CoreImage 还是慢)。除了速度上的优势,GPUImage 还提供了很多很棒的图像处理滤镜,但有时候这些基本功能仍然无法满足实际开发中的需求,不用担心 GPUImage 支持自定义滤镜。

安装GPUImage

  1. 把GPUImage.xcodeproj 拖到你的Xcode project
  2. 在app的target依赖设置里面添加GPUImage作为Target Dependency
  3. 在build phase的Link Binary With Libraries, 把libGPUImage.a加进来.
  4. 添加下面这些系统framework:
    CoreMedia
    CoreVideo
    OpenGLES
    AVFoundation
    QuartzCore
  5. 头文件搜索路径: project’s build settings, 把GPUImage的source和source下的iOS目录加到搜索路径里, 使用相对路径和递归.
  6. 包含下面这个头文件:
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
一个典型的例子

  1. 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
10
GPUImageView *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]