Implementation of Camera Real-time Filter on Android Platform--Basic Preparation Method of Filter

Original Link: https://my.oschina.net/wuhaoyu/blog/607825

You know how to make filters This question and answer The highest ticket in the list was given to a more professional answer

In addition, githunb once had an open source project, InstagramFilters, which gave some filter codes for the initial version of Instagram, of less than 20. Download Address GPUImage also has some image processing algorithms to learn

Let's talk about making filters:


1. Add a cover layer:


This kind of border is often found in Instagram, which is easy to implement. First, the picture is loaded into the texture, then the original RGB is multiplied by the RGB point of the graph. For example, the vec point in the shader is multiplied by the corresponding coordinates, such as the center of the original map (1., 1., 1.) and the center of the original map is unchanged after multiplying, while the corner, such as a point (.5,.5), is multiplied by the pattern RGB and then the original rbg is multiplied by the pattern rgb.Values are halved, resulting in a darkening effect.The final image will cover a border.


This kind of picture is common in some domestic filters. Unlike the above image, except for the effect to be added, the rest of the picture is black (0,0,0), so it cannot be dotted.You can modify it based on the following code

Sample code: (If you don't understand, you can refer to GPUImageAddBlendFilter and other codes in GPUImage)

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

2. Curve adjustment:

Color curve, the curve in PS, changes the picture effect by changing the value of RGB from 0 to 255 to the corresponding value according to the curve.The existing processing methods are basically implemented by table lookup, and the following methods are all table lookup.

1. Store curves in an array and pass data to textures via glTexImage2D:

The sample code is as follows:

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. Save as a 256-width picture and pass the picture to the texture:


The sample code is as follows:

  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. Mapping:

"(Reprint Knows It ) Designer's color effects from Photoshop are output on the following "grid plot". In App, the color change rule is obtained by parsing the "grid plot" and then applied to the photo.Note that only color adjustments (curves, color balance, etc.) can be made here, and other effects are limited to making use of changes in the blending mode between layers, such as dark angles, light leakage, etc."

These pictures can be found in some unencrypted APP s, such as:


Can be referred to This article Understand

Full code (from 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;
    <span style="white-space:pre">	</span>quad1.y = floor(blueColor/8.0); 
	quad1.x = floor(blueColor) - (quad1.y * 8.0);

	mediump vec2 quad2;
	quad2.y = floor(ceil(blueColor)/7.999); 
    <span style="white-space:pre">	</span>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);
    <span style="white-space:pre">	</span>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);
}


3. Hue (H), Saturation (S), Lightness (V) Adjustment:

These three attributes can be adjusted by converting RGB to HSV format for quick adjustment and then back

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); 
}


Reprinted at: https://my.oschina.net/wuhaoyu/blog/607825

Keywords: less REST

Added by SWD on Fri, 13 Sep 2019 00:52:40 +0300