GPUImage 自定義濾鏡

GPUImage 自定義濾鏡

GPUImage 是一個基於 GPU 圖像和視頻處理的開源 iOS 框架。因爲使用 GPU 來處理圖像和視頻,因此速度很是快,它的做者 BradLarson 稱在 iPhone4 上其處理速度是使用 CPU 來處理的 100 倍 (CoreImage 也能使用 GPU 來處理圖像,但我以爲 CoreImage 仍是慢)。除了速度上的優點,GPUImage 還提供了不少很棒的圖像處理濾鏡,但有時候這些基本功能仍然沒法知足實際開發中的需求,不用擔憂 GPUImage 支持自定義濾鏡。html

GPUImage 自定義濾鏡須要使用 OpenGL 着色語言( GLSL )編寫 Fragment Shader(片斷着色器),除此以外你可能還須要一點點圖像處理相關的知識。下面我將嘗試經過 GPUImage 中的 GPUImageColorInvertFilter(反色濾鏡)來說解一下它的運做過程。git

先看.h 文件:github

#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)。函數

第 二、3 行聲明瞭兩個變量。ui

varying 變量是Vertex 和 Fragment Shader(頂點着色器和片斷着色器)之間作數據傳遞用的,通常 Vertex Shader(頂點着色器) 修改 varying 變量的值,而後 Fragment Shader(片斷着色器)使用該varying變量的值。所以varying 變量在 Vertex 和 Fragment Shader 中聲明必須一致。放到這裏,也就是說 textureCoordinate 必須叫這個名字不能改。3d

highp 聲明 textureCoordinate 精度(相應的還有mediumplowp)。code

vec2 聲明textureCoordinate 是一個二維向量。orm

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 

相關文章
相關標籤/搜索