Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android平台Camera實時濾鏡實現方法探討(七)--濾鏡基本制作方法(一)

Android平台Camera實時濾鏡實現方法探討(七)--濾鏡基本制作方法(一)

編輯:關於Android編程

關於如何制作濾鏡,知乎的這篇問答中的最高票給了比較專業的回答

另外,githunb曾經有個開源項目InstagramFilters給出了Instagram中最初版本的一些濾鏡代碼,約不到20種,下載地址,GPUImage中也有一些圖像處理算法可供學習

下面我們一起來探討探討濾鏡的制作:

 

一.添加覆蓋層:

\

此種邊框多見於Instagram中,比較容易實現,首先將圖片加載到紋理,將原RGB與該圖RGB點乘即可,shader中vec點乘即對應坐標相乘,例如原圖中心為(1.,1.,1.)相乘後原圖中心不變,而邊角例如某點為(.5,.5,.5),與圖案rgb相乘後原rbg值均減半,造成變暗效果。最終原圖會覆蓋一個邊框。

\

這種圖片多見於國內一些濾鏡,與上圖不同,除了需要添加的效果外,其余部分均為黑色(0,0,0),因此不能點乘來覆蓋。可以在如下代碼基礎上修改

示例代碼:(如果不明白可以參考GPUImage中的GPUImageAddBlendFilter等代碼)

 

textureColor = 1.0 - ((1.0 - mask) * (1.0 - textureColor)); 

 

二.曲線調整:

顏色曲線,即PS中的曲線,根據曲線將RGB從0到255每個點的值更改為對應的值,即可更改圖片效果。現有的處理方法基本采用查表法來實現,下面幾種方法都屬於查表法。

1.將曲線存儲在數組中,通過glTexImage2D將數據傳遞給紋理:

示例代碼如下:

 

redCurveValue = texture2D(curve, vec2(redCurveValue, 0.0)).r; 
greenCurveValue = texture2D(curve, vec2(greenCurveValue, 0.0)).g; 
blueCurveValue = texture2D(curve, vec2(blueCurveValue, 0.0)).b; 

 

2.保存成寬度為256的圖片,將圖片傳遞給紋理:

 

\

示例代碼如下:

 

[plain] view plaincopy
  1. texel = vec3(
  2. texture2D(inputImageTexture3, vec2(texel.r, .16666)).r,
  3. texture2D(inputImageTexture3, vec2(texel.g, .5)).g,
  4. texture2D(inputImageTexture3, vec2(texel.b, .83333)).b);

    3.映射:

    “(轉載自知乎)設計師用 Photoshop 調出來的色彩效果輸出在了下面這種「格子圖」上,在 App 裡通過解析「格子圖」得到了色彩的變化規則,然後把這個規則應用在了照片上。注意,這裡只能進行顏色上的調整(曲線,色彩平衡等),其他效果調整也只限於利用圖層間混合模式的更改,例如可做暗角、漏光等效果。”

    這些圖片在一些未加密的APP種均能找到,例如:

    \

    可以參考這篇文章加以理解

    完整代碼(來自GPUImageLookupFilter):

     

    varying highp vec2 textureCoordinate;
    
    uniform sampler2D inputImageTexture;
    uniform sampler2D inputImageTexture2; // lookup texture
    
    void main()
    {
    	lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    
    	mediump float blueColor = textureColor.b * 63.0;
    
    	mediump vec2 quad1;
        	quad1.y = floor(blueColor/8.0); 
    	quad1.x = floor(blueColor) - (quad1.y * 8.0);
    
    	mediump vec2 quad2;
    	quad2.y = floor(ceil(blueColor)/7.999); 
        	quad2.x = ceil(blueColor) - (quad2.y * 8.0);
    
    	highp vec2 texPos1;
    	texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
    	texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
    
    	highp vec2 texPos2;
    	texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
        	texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
    
    	lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);
    	lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);
    
    	lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
    	gl_FragColor = vec4(newColor.rgb, textureColor.w);
    }

     

     

    三.色調(H),飽和度(S),明度(V)調整:

    這3個屬性的調整,可以先將RGB轉換為HSV格式來快速調整,之後再轉換回來

     

    vec3 rgb2hsv(vec3 c) 
    {
    	vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 
    	vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 
    	vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 
    	
    	float d = q.x - min(q.w, q.y); 
    	float e = 1.0e-10; 
    	return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 
    } 
    
    vec3 hsv2rgb(vec3 c) 
    { 
    	vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 
    	vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 
    	return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 
    }


     

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved