返回

OpenGL ES 滤镜 ——灰度/倒置/马赛克

见解分享

在上一篇文章《OpenGL ES 滤镜——分屏滤镜》中,我们介绍了分屏滤镜的实现方法。本篇文章是对上一篇文章的补充,我们将介绍另外几种滤镜的效果:灰度、倒置、马赛克、六边形马赛克、三角形马赛克。

灰度滤镜

灰度滤镜将图片中的所有颜色转换为灰度,而灰度的深浅由原图中的颜色值决定。实现灰度滤镜的着色器代码如下:

// 顶点着色器
attribute vec4 a_Position;
attribute vec2 a_TexCoord;

varying vec2 v_TexCoord;

void main() {
  gl_Position = a_Position;
  v_TexCoord = a_TexCoord;
}

// 片段着色器
uniform sampler2D u_Texture;

varying vec2 v_TexCoord;

void main() {
  vec4 color = texture2D(u_Texture, v_TexCoord);
  float gray = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
  gl_FragColor = vec4(gray, gray, gray, 1.0);
}

倒置滤镜

倒置滤镜将图片中的所有颜色取反,即白色变黑色,黑色变白色。实现倒置滤镜的着色器代码如下:

// 顶点着色器
attribute vec4 a_Position;
attribute vec2 a_TexCoord;

varying vec2 v_TexCoord;

void main() {
  gl_Position = a_Position;
  v_TexCoord = a_TexCoord;
}

// 片段着色器
uniform sampler2D u_Texture;

varying vec2 v_TexCoord;

void main() {
  vec4 color = texture2D(u_Texture, v_TexCoord);
  gl_FragColor = vec4(1.0 - color.rgb, 1.0);
}

马赛克滤镜

马赛克滤镜将图片分割成一个个小方格,每个小方格内的颜色取方格内所有像素颜色的平均值。实现马赛克滤镜的着色器代码如下:

// 顶点着色器
attribute vec4 a_Position;
attribute vec2 a_TexCoord;

varying vec2 v_TexCoord;

uniform float u_MosaicSize;

void main() {
  gl_Position = a_Position;
  v_TexCoord = a_TexCoord;
}

// 片段着色器
uniform sampler2D u_Texture;

varying vec2 v_TexCoord;

uniform float u_MosaicSize;

void main() {
  vec2 texCoord = v_TexCoord * u_MosaicSize;
  vec4 color = vec4(0.0);
  for (float i = 0.0; i < u_MosaicSize; i++) {
    for (float j = 0.0; j < u_MosaicSize; j++) {
      color += texture2D(u_Texture, texCoord + vec2(i, j) / u_MosaicSize);
    }
  }
  gl_FragColor = color / (u_MosaicSize * u_MosaicSize);
}

六边形马赛克滤镜

六边形马赛克滤镜将图片分割成一个个小六边形,每个小六边形内的颜色取六边形内所有像素颜色的平均值。实现六边形马赛克滤镜的着色器代码如下:

// 顶点着色器
attribute vec4 a_Position;
attribute vec2 a_TexCoord;

varying vec2 v_TexCoord;

uniform float u_MosaicSize;

void main() {
  gl_Position = a_Position;
  v_TexCoord = a_TexCoord;
}

// 片段着色器
uniform sampler2D u_Texture;

varying vec2 v_TexCoord;

uniform float u_MosaicSize;

void main() {
  vec2 texCoord = v_TexCoord * u_MosaicSize;
  vec4 color = vec4(0.0);
  for (float i = 0.0; i < u_MosaicSize; i++) {
    for (float j = 0.0; j < u_MosaicSize; j++) {
      float x = texCoord.x + i / u_MosaicSize;
      float y = texCoord.y + j / u_MosaicSize;
      float dist = sqrt(pow(x - 0.5, 2) + pow(y - 0.5, 2));
      if (dist < 0.5) {
        color += texture2D(u_Texture, texCoord + vec2(i, j) / u_MosaicSize);
      }
    }
  }
  gl_FragColor = color / (u_MosaicSize * u_MosaicSize);
}

三角形马赛克滤镜

三角形马赛克滤镜将图片分割成一个个小三角形,每个小三角形内的颜色取三角形内所有像素颜色的平均值。实现三角形马赛克滤镜的着色器代码如下:

// 顶点着色器
attribute vec4 a_Position;
attribute vec2 a_TexCoord;

varying vec2 v_TexCoord;

uniform float u_MosaicSize;

void main() {
  gl_Position = a_Position;
  v_TexCoord = a_TexCoord;
}

// 片段着色器
uniform sampler2D u_Texture;

varying vec2 v_TexCoord;

uniform float u_MosaicSize;

void main() {
  vec2 texCoord = v_TexCoord * u_MosaicSize;
  vec4 color = vec4(0.0);
  for (float i = 0.0; i < u_MosaicSize; i++) {
    for (float j = 0.0; j < u_MosaicSize; j++) {
      float x = texCoord.x + i / u_MosaicSize;
      float y = texCoord.y + j / u_MosaicSize;
      float dist = sqrt(pow(x - 0.5, 2) + pow(y - 0.5, 2));
      if (dist < 0.5) {
        color += texture2D(u_Texture, texCoord + vec2(i, j) / u_MosaicSize);
      }
    }
  }
  gl_FragColor = color / (u_MosaicSize * u_MosaicSize);
}

应用

灰度滤镜、倒置滤镜、马赛克滤镜、六边形马赛克滤镜、三角形马赛克滤镜在图像处理中都有着广泛的应用,例如:

  • 图像去噪: 马赛克滤镜可以有效去除图像中的噪声。
  • 图像锐化: 灰度滤镜可以增强图像的边缘。
  • 图像艺术效果: 倒置滤镜、六边形马赛克滤镜、三角形马赛克滤镜可以 tạo ra 各种各样的艺术效果。

结论

本文介绍了 OpenGL ES 中灰度滤镜、倒置滤镜、马赛克滤镜、六边形马赛克滤镜、三角形马赛克滤镜的实现方法。这些滤镜在图像处理中有着广泛的应用,掌握这些滤镜的实现方法可以帮助我们开发出更加复杂、美观的图像处理应用程序。