background

The little red book is one of the many young people like software, inside a lot of beautiful little sister, little sister itself is beautiful is a fact, but without good filter processing, miss beautiful want to make a discount, the sisters on the analysis of the technology of the little red book can be seen a little red book in this a piece of audio and video input is also very big, VE and AE are relatively good, I also often use Xiaohongshu, as an audio and video development engineer, when I see the audio and video functions inside, I can not help but want to start to see how to do it. In this paper, we will analyze a picture processing filter of Xiaohongshu — color adjustment module.

As can be seen from the screenshot above, there are five types of color adjustment in Xiaohongbook: brightness, contrast, color temperature, saturation and granularity, as well as a sharpness, which is not mentioned in Xiaohongbook. Later we can have more food.

brightness

  varying highp vec2 textureCoordinate;

  uniform sampler2D inputImageTexture;
  uniform lowp float brightness;

  void main() {
    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.a);
  }
Copy the code

To adjust the brightness, you can change the brightness range from -1.0F to 1.0F with the original picture.

contrast

varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform lowp float contrast; void main() { lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); Gl_FragColor = vec4(((texturecolor.rgb-vec3 (0.5)) * contrast), texturecolor.a); }Copy the code

Adjust brightness by adjusting contrast. The range of contrast adjustment is from 0.0F to 2.0F, where 1.0F represents the original picture.

Color temperature

uniform sampler2D inputImageTexture; varying highp vec2 textureCoordinate; uniform lowp float temperature; uniform lowp float tint; Const lowp warmFilter = VEC3 (0.93, 0.54, 0.0); Const mediump mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311); Const mediump mat3yiqtorgb = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702); const mediump mat3yiqtorgb = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702); void main() { lowp vec4 source = texture2D(inputImageTexture, textureCoordinate); mediump vec3 yiq = RGBtoYIQ * source.rgb; Yiq. B = clamp(YIQ. B + TINT *0.5226*0.1, -0.5226, 0.5226); lowp vec3 rgb = YIQtoRGB * yiq; ((rgb.r < 0.5? (2.0 * RGB. R * warmFilter. R), (1.0-2.0 * (1.0 - RGB. R) * (1.0 - warmFilter. R))), (RGB) g < 0.5? (2.0 * RGB. G * warmFilter. G), (1.0-2.0 * (1.0 - RGB. G) * (1.0 - warmFilter. G))) and b (RGB) < 0.5? (2.0 * RGB. B * warmFilter. B), (1.0-2.0 * (1.0 - RGB. B) * (1.0 - warmFilter. B)))); gl_FragColor = vec4(mix(rgb, processed, temperature), source.a); }Copy the code

The color temperature ranges from 2000.0F to 8000.0F, where 5000.0F indicates the original image, and the hint parameter defaults to 0.0F.

The following three pictures, the first is the original picture, the second chapter is warm color, the third chapter is cold color.

saturation

varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform lowp float saturation; Const Mediump Vec3 luminanceWeighting = VEC3 (0.2125, 0.7154, 0.0721); void main() { lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp float luminance = dot(textureColor.rgb, luminanceWeighting); lowp vec3 greyScaleColor = vec3(luminance); gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.a); }Copy the code

Saturation refers to the brightness of the colors of images, which is adjusted by adjusting saturation. Saturation ranges from 0.0f to 2.0 F, in which 1.0 F refers to the original figure. The greater the saturation is, the brighter the colors are. Otherwise, the more monotonous the colors are.

granularity

varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; Uniform LOWP float grain; void main() { lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); Float noise = (sine (dot(textureCoordinate, vec2(12.9898, 78.233) * 2.0)) * 43758.5453)); gl_FragColor = textureColor - noise * grain }Copy the code

The grain size is adjusted by adjusting the grain parameter. The grain size ranges from 0.0F to 0.5F, where 0.0F represents the original image.

Below, take a look at the particle size adjustment diagram under the condition of 0.5F: the overall particle sense is still very strong.

The original image is:

sharpness

Vertex shader

attribute vec4 position; attribute vec4 inputTextureCoordinate; uniform float imageWidthFactor; uniform float imageHeightFactor; uniform float sharpness; varying vec2 textureCoordinate; varying vec2 leftTextureCoordinate; varying vec2 rightTextureCoordinate; varying vec2 topTextureCoordinate; varying vec2 bottomTextureCoordinate; varying float centerMultiplier; varying float edgeMultiplier; void main() { gl_Position = position; Vec2 widthStep = vec2(imageWidthFactor, 0.0); Mediump = vec2(0.0, imageHeightFactor); textureCoordinate = inputTextureCoordinate.xy; leftTextureCoordinate = inputTextureCoordinate.xy - widthStep; rightTextureCoordinate = inputTextureCoordinate.xy + widthStep; topTextureCoordinate = inputTextureCoordinate.xy + heightStep; bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep; CenterMultiplier = 1.0 + 4.0 * sharpness; edgeMultiplier = sharpness; }Copy the code

Chip shader

  precision highp float;

  varying highp vec2 textureCoordinate;
  varying highp vec2 leftTextureCoordinate;
  varying highp vec2 rightTextureCoordinate;
  varying highp vec2 topTextureCoordinate;
  varying highp vec2 bottomTextureCoordinate;

  varying highp float centerMultiplier;
  varying highp float edgeMultiplier;

  uniform sampler2D inputImageTexture;

  void main() {
    mediump vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb;
    mediump vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
    mediump vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
    mediump vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;
    mediump vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;

    gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier +
            rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier +
            bottomTextureColor * edgeMultiplier)), texture2D(inputImageTexture, bottomTextureCoordinate).a);
  }
Copy the code

Sharpness is actually the pixels that detect the edges of the pixels in an image, making the whole image stand out and contrast very strong. Sharpness adjustment is achieved through sharpness. The adjustment range is -4.0F to 4.0F, and 0.0F represents the original image.

Here is an image with a sharp style.