Android平臺Camera實時濾鏡實現方法探討(四)--以Hefe濾鏡爲例

上文講到如何將YUV轉換成RGB,之後就可以根據自己的設計,製作自己需要的濾鏡了,例如將紅色變的更紅,增加亮度等。本文以Instagram上的Hefe濾鏡爲例

濾鏡的製作,基本上採用圖層+曲線,結合一些其他屬性的調節,例如這篇文章講解了如何用PS模擬Instagram上的濾鏡。

1.添加邊框

下面是從Instagram中找到的圖片資源,首先是添加邊框


將圖片載入bitmap,然後將圖片綁定給紋理,獲取紋理索引

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
			
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

然後交給shader

// Set program handles
inputUniformHandler2 = glGetUniformLocation(gProgram, "inputImageTexture2");
// Set the active texture1 unit to texture unit 2.
glActiveTexture(GL_TEXTURE2);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, inputTextureHandler2);
// Tell the texture uniform sampler to use this texture in the shader by
// binding to texture unit 1.
glUniform1i(inputUniformHandler2, 2);


獲取邊框RGB

vec3 edge = texture2D(inputImageTexture2, textureCoordinate).rgb;

向量點乘,疊加,將邊框加到原圖之上,texel爲原rgb數據

texel = texel * edge;

在shader中,rgb數據用0.0~1.0之間表示,例如color.r=0.2代表20%的紅色,例如邊框中心rgb都是1,因此,中心是不變的,而邊緣部分會根據邊框的RGB值改變,相當於將邊框覆蓋到原圖之上。


2.改變RGB值

根據設計的效果改變RGB值,類似於PS中的曲線,可以採用單獨寫一個函數來完成,Instagram等APP採用一個255X3像素圖片來完成,3個像素從上到下分別爲R/G/B,從左到右分別代表原RGB0~255所對應的值。新的R/G/B即原來的R/G/B的值在改圖對應位置的值。例如原爲126的R值,即在shader中爲0.5,即對應的新R值爲該圖紅色中間位置的R值。


代碼如下:

texel = vec3(
    texture2D(inputImageTexture3, vec2(texel.r, .16666)).r,
    texture2D(inputImageTexture3, vec2(texel.g, .5)).g,
    texture2D(inputImageTexture3, vec2(texel.b, .83333)).b);

3.添加其他紋理圖

下圖是來自Instagram的hefe濾鏡,需要根據右圖進行調整

                         

代碼如下:

vec3 metal = texture2D(inputImageTexture6, textureCoordinate).rgb;
vec3 metaled = vec3(
                    texture2D(inputImageTexture5, vec2(metal.r, texel.r)).r,
                    texture2D(inputImageTexture5, vec2(metal.g, texel.g)).g,
                    texture2D(inputImageTexture5, vec2(metal.b, texel.b)).b
                    );
先取出左圖的RGB值,然後根據原圖(預覽畫面)的RGB值到右圖中去取值,例如原圖中某點灰色圖片的RGB值爲(167,173,167),預覽畫面爲棕色(125,125,125),即新的RBG值分別爲右圖中座標爲(0.65,0.5),(0.678,0.5),(0.65,0.5),將新的值繪製到屏幕中。

4.濾鏡強度

如果需要調節濾鏡強度,定義一個float變量,採用mix函數調節

metaled.rgb = mix(originColor.rgb, metaled.rgb, p1);

gl_FragColor = vec4(metaled, 1.0);

理想效果:(來自網絡)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章