GPUImage框架分析

2,240 阅读4分钟

GPUImage 简介

可以直接在GPUImage的Github了解,这里就不赘述。

官方Github链接:github.com/BradLarson/…

GPUImage对比Core Image

GPUImage

  • 最低支持iOS4.0,iOS5.0之后就支持自定义滤镜
  • 在低端机上,GPUImage有更好的表现
  • GPUImage在视频处理上有更好的表现
  • GPUImage的代码完全公开,实现透明
  • 可以根据自己的业务需求,定制更加复杂的管线操作(可定制程度高)
  • GPUImage当处理超过纹理限制的图像的时候,会先做判断,压缩成最大纹理限制的图像,导致图像质量损失

Core Image

  • 官方框架,使用放心,维护方便
  • 支持CPU渲染,可以在后台继续处理和保存图片
  • 一些滤镜的性能更强劲,例如由Metal Performance Shaders支持的模糊滤镜等
  • Metal, SpriteKit, SceneKit, Core Animation可以更完美的配合
  • 支持图像识别功能,包括人脸识别、条形码识别、文本识别等
  • 支持自动增强图像效果,会分析图像的直方图,图像属性,脸部区域,然后通过一组滤镜来改善图像效果
  • 支持对原生RAW格式图片的处理
  • 滤镜链的性能比GPUImage
  • 支持对大图进行处理,超过GPU纹理限制(4096 * 4096)的时候,会自动拆分成几个小块处理(Automatic tiling)

GPUImage特性

  • 丰富的输入组件:摄像头、图片、视频、OpenGL纹理、二进制数据、UIElement(UIVIew, CALayer)
  • 大量现成的内置滤镜(4大类):
  1. 颜色类(亮度、色度、饱和度、对比度、曲线、白平衡...)
  2. 图像类(仿射变换、裁剪、高斯模糊、毛玻璃...)
  3. 颜色混合类(差异混合、alpha混合、遮罩混合...)
  4. 效果类(像素画、素描效果、压花效果、球形玻璃效果...)
  • 丰富的输出组件:UIView、视频文件、GPU纹理、二进制数据
  • 灵活的滤镜链:滤镜效果之间可以互相串联、并联,调用管理相当灵活
  • 接口易用,滤镜和OpenGL资源的创建及使用都做了统一的封装,简单易用,并且内置了一个cache模块实现了framebuffer的复用
  • 线程管理:OpenGLContext不是多线程安全的,GPUImage创建了专门的contextQueue,所有的滤镜都会扔到统一的线程中处理
  • 轻松实现自定义滤镜效果:继承GPUImageFilter自动获得上面全部特性,无需关注上下文的环境搭建,专注于效果的核心算法实现即可

滤镜链起点

  • GPUImagePicture 用来处理静态图片,本质:解压图片->纹理->滤镜处理
  • GPUImageRawDataInput 二进制数据->纹理图片
  • GPUImageTextureInput 纹理数据
  • GPUImageUIElement UIVIew/CALayer -> 图像数据 -> 纹理 比如可以将一个UILabel做成水印
  • GPUImageMovie 视频文件 -> AVAssetReader -> 逐帧读取视频 -> 帧数据转化成纹理 -> 滤镜处理 AVAssetReaderOutput -> CMSampleBufferRef -> CVImageBUfferRef -> CVOpenGLESTextureRef -> Texture
  • GPUImageVideoCamera 基于AVFoundation -> didOutPutSampleBuffer
  • GPUImageStillCamera

滤镜

基类:GPUImageFilter

GPUImage和CoreImage已经实现了将近200个滤镜效果,GPUImage库中提供的大部分滤镜都是通过片元着色器的一系列操作来实现相应的效果,大部分滤镜都是对图片中的像素进行计算产生新的像素颜色处理,滤镜处理的原理:将静态图片或者视频的每一帧进行图形变换后再显示到屏幕上,其本质就是像素点的位置和颜色的变化。

滤镜终点

  1. GPUImageMovieWriter AVAssetWriter把每一帧纹理的数据从帧缓冲区写入到指定文件
  2. GPUImageRawDataOutput 滤镜帧缓冲区的二进制数据
  3. GPUImageTextureOutput
  4. GPUImageView

GPUImage框架解析

GPUImage框架采用的链式(Chain)结构,主要由一个GPUImageOutput interfaceGPUImageInput porocol串联起来。

GPUImageOutput负责输出纹理Texture GPUImageInput负责输入纹理Texture

整个链式图像数据过程,纹理作为核心载体,当然GPUImage不仅仅适用于静态图片,还适用视频、实时拍摄等,这些不同的载体都是继承于GPUImageOutput类。

基本上每一个滤镜都是继承自GPUImageFilter,而GPUImageFilter是整套框架的核心,接收一个GPUImageFrameBuffer输入,调用GLProgram渲染处理之后,输出一个GPUImageFrameBuffer,再把输出的GPUImageFrameBuffer传给通过targets属性关联的下一级滤镜,直到传递给最终的输出组件。

源码结构分析

image.png

image.png

总结

GPUImage是一套主流的图像处理框架,很多直播、美图APP都采用此技术,无论项目业务需要决定使用GPUImage还是Core Image,它们都是相当成熟的工具。