GPUImage 自定义滤镜

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

GPUImage 自定义滤镜需要使用 OpenGL 着色语言( GLSL )编写 Fragment Shader(片段着色器),除此之外你可能还需要一点点图像处理相关的知识。下面我将尝试通过 GPUImage 中的 GPUImageColorInvertFilter(反色滤镜)来讲解一下它的运作过程。

先看.h 文件:

#import "GPUImageFilter.h"

@interface GPUImageColorInvertFilter : GPUImageFilter
{
} @end

很简单,可以看出 GPUImageColorInvertFilter 是继承了 GPUImageFilter

然后看 .m 文件 中 @implementation 之前的一段代码

NSString *const kGPUImageInvertFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.a);
}
);

第 1 行,可以看到 SHADER_STRING 宏中包含着我们的 Shader (着色器)代码,我们的着色器字符串赋给一个 const NSString 对象(这个常量将在 GPUImageFilter 及其子类的初始化过程中用来设置 filter)。

第 2、3 行声明了两个变量。

varying 变量是Vertex 和 Fragment Shader(顶点着色器和片段着色器)之间做数据传递用的,一般 Vertex Shader(顶点着色器) 修改 varying 变量的值,然后 Fragment Shader(片段着色器)使用该varying变量的值。因此varying 变量在 Vertex 和 Fragment Shader 中声明必须一致。放到这里,也就是说 textureCoordinate 必须叫这个名字不能改。

highp 声明 textureCoordinate 精度(相应的还有mediumplowp)。

vec2 声明textureCoordinate 是一个二维向量。

uniform 声明 inputImageTexture 是外部程序传递给 Shader 的变量, Shader 程序内部只能用,不能改。 sampler2D 声明变量是一个2D纹理。

第 4 行,相信你并不陌生,没错儿 Shader 也是从 main() 函数开始执行的。

第 5 行,texture2D 纹理取样器,根据纹理坐标返回纹理单元的值。

第 6 行,(1.0 - textureColor.rgb) 去 textureColor也就是原图的 RGB 值,做了一个向量的减法,这是图像的反色算法,然后把经过反色的 RGB 值和原图的 Alpha 值组成一个新的 vec4(四维向量)值赋给 gl_FragColor。 gl_FragColor 是 Fragment Shader 预先定义的变量,赋给它的值就是该片段最终的颜色值。

Shader 到这里已经解释完了,可能你依然云里雾里,我来说一下我对这部分功能的理解,可能不对,但目前是管用的,方便你理解:GPUImage 中应该有一个 Vertex Shader,它对图像逐个像素扫描,通过 textureCoordinate 变量将当前的扫描坐标传递给我们的 Fragment Shader,inputImageTexture包含我们要处理的图像的全部信息,在 Shader 程序内部通过 texture2D 得到 inputImageTexture 在当前位置 textureCoordinate 的 RGBA 值,运用图像处理知识,算出想要的新的 RGBA 值,把结果值赋给 gl_FragColor就算完成了。

现在我们继续看代码,在 Shader 之后是 GPUImageColorInvertFilter 的实现:

@implementation GPUImageColorInvertFilter

- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageInvertFragmentShaderString]))
{
return nil;
} return self;
} @end

很简单,就是使用刚才的着色器代码来设置 filter。这样一个新的滤镜就诞生了~

网路上关于 GPUImage 自定义滤镜 和 GLSL 的资料不是特别多,我斗胆把自己摸索到的理解在这里和你分享,希望对你有所帮助,如有错误指出欢迎指出,另外,可以去这里查阅 OpenGL GLSL 文档,玩的愉快 (●°u°●)​ 」

from : http://www.itiger.me/?p=143&utm_source=tuicool

GPUImage 自定义滤镜的更多相关文章

  1. 利用iOS原生系统进行人脸识别+自定义滤镜(GPUImage)

    人脸识别+滤镜效果(基于GPUImage实现的自定义滤镜) 最近碰到一个好玩的需求.说要客户端这边判定一下是否有人脸.在有的基础上.对相片做进一步的美化滤镜处理. 首先是人脸的识别判定; //将图片对 ...

  2. GPUImage处理图片(滤镜)

    GPUImage 是基于 GPU 处理图像的一个开源库, 提供了各种图像处理滤镜,例如调 亮度/饱和度/曝光度/白平衡/锐化等滤镜. 并且支持照相机/摄像机 的实时滤镜. GPUImage采用链式方式 ...

  3. GPUimage实时滤镜的实现

    GPUIMAGE中GPUImageStillCamera可以调用系统相机,并实现实时滤镜,但是我没有找到相机全屏的方法,望知道的说一下 GPUImageStillCamera继承自GPUImageVi ...

  4. 导入GPUImage,实时滤镜相机,GUPImage遇到的问题解决,_OBJC_METACLASS_$_GBGPUImageView in GBGPUImageView.o

    导入方法转自:http://www.cnblogs.com/S2-huai/p/3881349.html.. (原文:http://www.cnblogs.com/YouXianMing/p/3709 ...

  5. GPUImage简单滤镜使用(二)

    GPUImage中,提供了许多简单的的常用的滤镜.在上一篇文章讲了如何调节图像的亮度这片文章讲一下如何通过GPUImage调节图像的对比度,饱和度,曝光度,和白平衡(美图秀秀中的色温). 原图像 调整 ...

  6. GPUImage简单滤镜使用(一)

    今天来学习一下一个简单滤镜使用的流程,通过调节亮度滤镜来了解.先将GPUImage库导入到项目中,引入头文件"GPUImage.h"   一.创建亮度滤镜对象    GPUImag ...

  7. GPUImage简单滤镜使用之色阶(三)

    色阶是表示图像亮度强弱的指数标准,图像的色彩丰满度和精细度是由色阶决定的.在GPUImage中GPUImageLevelsFilter提供了此功能. GPUImageLevelsFilter定义了修改 ...

  8. 自定义滤镜 ColorMatrixFilter

    var url:URLRequest = new URLRequest("Koala.jpg"); var l:Loader = new Loader(); l.contentLo ...

  9. iOS滤镜系列-滤镜开发概览

    概述 滤镜最早的出现应该是应用在相机镜头前实现自然光过滤和调色的镜片,然而在软件开发中更多的指的是软件滤镜,是对镜头滤镜的模拟实现.当然这种方式更加方便快捷,缺点自然就是无法还原拍摄时的真实场景,例如 ...

随机推荐

  1. 层层递进Struts1(七)详解DispatchAction

    通过前面几篇博客,不知道大家有没有发现这个问题,虽然现在可以灵活控制跳转了,但是Action的数量还是比较多,如何既能保证跳转灵活,还能减少Action的数量?这就是我们这篇博客所说的Dispatch ...

  2. Please check if the Publishing Tools on the server (System/PublishingTools) are started.

    ArcMap或ArcCatalog中双击连接到Server即可,该工具即自动可启动

  3. mysql in查询 结果乱序 引发的思考

    Mysql in查询 结果集 乱序 SQL: select * from table where id IN (3,6,9,1,2,5,8,7); 这样的情况取出来后,其实,id还是按1,2,3,4, ...

  4. UVa11925 Generating Premutations

    留坑(p.254) #include<cstdio> #include<cstring> #include<cstdlib> #include<algorit ...

  5. Huffman树及其应用

    哈夫曼树又称为最优二叉树,哈夫曼树的一个最主要的应用就是哈夫曼编码,本文通过简单的问题举例阐释哈夫曼编码的由来,并用哈夫曼树的方法构造哈夫曼编码,最终解决问题来更好的认识哈夫曼树的应用--哈夫曼编码. ...

  6. SQL 按月统计(两种方式) 分类: SQL Server 2014-08-04 15:36 154人阅读 评论(0) 收藏

    (1)Convert 函数 select Convert ( VARCHAR(7),ComeDate,120) as Date ,Count(In_code) as 单数,Sum(SumTrueNum ...

  7. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请 系列目录 创建新表单之后,我们就可以起草申请了,申请按照严格的表单步骤和分 ...

  8. hdu-5009-Paint Pearls-dp

    由题意我们能够知道,花费最多为n. 所以单次最多涂掉sqrt(n)种颜色. dp[i]:涂到第i个位置.之前的花费最少为多少. biao[i][j]:在第i个位置,往前涂j-1种颜色,涂到哪个位置. ...

  9. 原生JS添加节点方法与jQuery添加节点方法的比较及总结

    一.首先构建一个简单布局,来供下边讲解使用 1.HTML部分代码: <div id="div1">div1</div> <div id="d ...

  10. HTML5 ArrayBufferView之DataView

    DataView视图 如果一段数据包括多种类型(比如服务器传来的HTTP数据),这时除了建立ArrayBuffer对象的复合视图以外,还可以通过DataView视图进行操作. DataView视图提供 ...