GPUImage 初探

简介

GPUImage是一个基于OpenGL ES 2.0的开源的图像处理库,作者是Brad Larson。GPUImageOpenGL ES封装为简洁的Objective-CSwift接口,可以用来给图像、实时相机视频、电影等添加滤镜。

目前GPUImage有三个版本:

  • 1.0版本是OC + OPenGL ES
    GPUImage1.0

  • 2.0版本是Swift + OPenGL ES
    GPUImage2.0

  • 3.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大类)

    1. 颜色类(亮度、色度、饱和度、对比度、曲线、白平衡..)
    2. 图像类(仿射变换、裁剪、高斯模糊、毛玻璃效果..)
    3. 颜色混合类(差异混合、alpha混合、遮罩混合..)
    4. 效果类(像素化、素描效果、压花效果、球形玻璃效果..)
  • 丰富的输出组件UIView 、视频文件、GPU纹理、二进制数据

  • 灵活的滤镜链滤镜效果之间可以相互串联、并联,调用管理相当灵活。

  • 接口易用,滤镜和OpenGL资源的创建及使用都做了统一的封装,简单易用,并且内置了一个cache模块实现了framebuffer 的复用。

  • 线程管理OpenGLContext不是多线程安全的, GPUImage创建了专的contextQueue,所有的滤镜都会扔到统一的线程中处理。

  • 轻松实现自定义滤镜效果继承GPUImageFilter自动获得上面全部特性,无需关注上下文的环境搭建,专注于效果的核心算法实现即可。

使用流程

GPUImage的使用主要分为三部分:

  1. 滤镜链起点: 输入数据
  2. 滤镜: 处理数据
  3. 滤镜链终点: 输出数据
  • 流程图


滤镜链起点
  1. GPUImagePicture: 用来处理静态图片.本质解压图片->纹理->用滤镜来进行处理.
  2. GPUImageRawDataInput: 二进制数据->纹理图片. CVPixelFormat
  3. GPUImageTextureInput: 用纹理数据.
  4. GPUImageUIElement: UIView/CAL ayer ->图像数据->纹理.
  5. GPUImageMovie: 视频文件-> AVAssetReader -> 逐帧读取视频->帧数据转化成纹理->滤镜处理.AVAssetReader0utput -> CMSamplerBufferRef -> CVImageBufferRef ->CVOpenGLESTextureRef -> Texture
  6. GPUImageVi deoCamera: 基于AVFundation -> didoutPutSampleBuffer
  7. 子类(GPUImageStillCamera)
滤镜
  1. GPUImageFilter及其子类: 目前GPUImage大概有200多个滤镜,这里不一一赘述.如果需要自定义滤镜,只需要一个继承于GPUImageFilter.并根据需求修改即可.
滤镜终点
  1. GPUImageMoviewWriter: AVAssetWriter把每-帧纹理的数据从帧缓存区->指定文件.
  2. GPUImageRawData0utput: 处理滤镜帧缓存区的二进制数据
  3. GPUImage TextureOutput
  4. GPUlmageView

框架解析

  • GPUImage框架采用的链式( Chain )结构.
  • 主要有一个GPUImageoutput interfaceGPUImageInput 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;

你可能感兴趣的:(GPUImage 初探)