简介
GPUImage是一个基于OpenGL ES 2.0
的开源的图像处理库,作者是Brad Larson。GPUImage
将OpenGL ES
封装为简洁的Objective-C
或Swift
接口,可以用来给图像、实时相机视频、电影等添加滤镜。
目前GPUImage有三个版本:
1.0版本是OC + OPenGL ES
GPUImage1.02.0版本是Swift + OPenGL ES
GPUImage2.03.0版本是Swift + Metal
GPUImage3.0
与Core Image区别
对于图像的处理苹果官方提供了Core Image框架,那么GPUImage和Core Image有哪些区别呢?
GPUImage
- 最低支持
iOS 4.0
,iOS 5.0
之后就支持自定义滤镜 - 在低端机型上,
GPUImage
有更高的表现(GPUImage作者自己说的) - GPUImage 在视频处理上有更好的表现.
- GPUImage 代码完全开源,实现透明.
- 可以根据自己的业务需求,定制更加复杂的管线操作.可定制程度高.
Core Image
-
官方框架
,使用放心,维护方便.不用担心哪天框架不更新了,就算废弃了,苹果也会提供代替方案,不用自己操心. - 支持
CPU
渲染,可以在后台继续处理和保存图片. - 支持使用
Metal
渲染图像,而Metal在iOS 平台上有更好的表现. - 与
Metal
,SpriteKit
,Core Animation
等更完美的配合. - 支持
图像识别功能.包括人脸识别,条形码识别,文本识别
等. - 支持自动增强图像效果,会分析图像的直方图,图像属性,脸部区域,然后通过一组滤镜来改善图像效果.
- 支持对原生
RAW
格式图片的处理. - 滤镜链的性能比
GPUImage
高.(GPUImage作者自己说的) - 支持对大图进行处理,超过GPU纹理限制
4096 * 4096
的时候,会自动拆分成几个小块处理(Automatic tiling).GPUImage对大图的处理方案则是压缩图片到最大纹理限制,会导致图像质量损失.
GPUImage特性
丰富的输入组件摄像头、图片、视频、OpenGL纹理、二进制数据、UIElement (UIView, CALayer)
-
大量现成的内置滤镜(4大类)
-
颜色类
(亮度、色度、饱和度、对比度、曲线、白平衡..) -
图像类
(仿射变换、裁剪、高斯模糊、毛玻璃效果..) -
颜色混合类
(差异混合、alpha混合、遮罩混合..) -
效果类
(像素化、素描效果、压花效果、球形玻璃效果..)
-
丰富的输出组件UIView 、视频文件、GPU纹理、二进制数据
灵活的滤镜链滤镜效果之间可以相互串联、并联,调用管理相当灵活。
接口易用,滤镜和OpenGL资源的创建及使用都做了统一的封装,简单易用,并且内置了一个cache模块实现了framebuffer 的复用。
线程管理OpenGLContext不是多线程安全的, GPUImage创建了专的contextQueue,所有的滤镜都会扔到统一的线程中处理。
轻松实现自定义滤镜效果继承GPUImageFilter自动获得上面全部特性,无需关注上下文的环境搭建,专注于效果的核心算法实现即可。
使用流程
GPUImage的使用主要分为三部分:
- 滤镜链起点:
输入数据
- 滤镜:
处理数据
- 滤镜链终点:
输出数据
-
流程图
滤镜链起点
- GPUImagePicture: 用来处理静态图片.本质解压图片->纹理->用滤镜来进行处理.
- GPUImageRawDataInput: 二进制数据->纹理图片. CVPixelFormat
- GPUImageTextureInput: 用纹理数据.
- GPUImageUIElement: UIView/CAL ayer ->图像数据->纹理.
- GPUImageMovie: 视频文件-> AVAssetReader -> 逐帧读取视频->帧数据转化成纹理->滤镜处理.
AVAssetReader0utput -> CMSamplerBufferRef -> CVImageBufferRef ->CVOpenGLESTextureRef -> Texture
- GPUImageVi deoCamera: 基于AVFundation -> didoutPutSampleBuffer
- 子类(GPUImageStillCamera)
滤镜
- GPUImageFilter及其子类: 目前GPUImage大概有200多个滤镜,这里不一一赘述.如果需要自定义滤镜,只需要一个继承于GPUImageFilter.并根据需求修改即可.
滤镜终点
- GPUImageMoviewWriter: AVAssetWriter把每-帧纹理的数据从帧缓存区->指定文件.
- GPUImageRawData0utput: 处理滤镜帧缓存区的二进制数据
- GPUImage TextureOutput
- GPUlmageView
框架解析
- GPUImage框架采用的链式( Chain )结构.
- 主要有一个
GPUImageoutput interface
和GPUImageInput protocol
串联起来. - GPUImageOutput负责
输出
纹理Texture ; - GPUImageInput负责
输入
纹理Texture ;
整个链式图像数据过程,纹理作为核心载体.当然GPUImage 不仅仅适用于静态图
片,还适用视频,实时拍摄等.那这些不同的载体都是继承于GPUImageOutput 类
基本上每一个滤镜都是继承自GPUImageFilter
而GPUImageFilter 是整套框架
的核心.接收一个GPUImageFrameBuffer输入
,调用GLProgram渲染处理
之后,输出一个 GPUImageFrameBuffer
.在把输出的GPUImageFrameBuffer传给通过targets
属性关联的下一级滤镜
.直到传递给最终的输出组件.
示例代码
//1.获取图片
_myImage = [UIImage imageNamed:@"my.jpeg"];
//2.初始化饱和度滤镜
_disFilter = [[GPUImageSaturationFilter alloc]init];
//设置饱和度值
_disFilter.saturation = 1.0;
//设置要渲染的区域 --图片大小
[_disFilter forceProcessingAtSize:_myImage.size];
//使用单个滤镜
[_disFilter useNextFrameForImageCapture];
//3.创建图片组件--输入数据(静态图片)
GPUImagePicture *stillImageSoucer = [[GPUImagePicture alloc]initWithImage:_myImage];
//为图片添加一个滤镜
[stillImageSoucer addTarget:_disFilter];
//处理数据(图片)
[stillImageSoucer processImage];
//4.处理完成,从FrameBuffer帧缓存区中获取图片--输出数据
UIImage *newImage = [_disFilter imageFromCurrentFramebuffer];
//更新图片
_myImagView.image = newImage;