Skip to content

自定义滤镜

本指南介绍如何通过继承 GPUPixel 中的 Filter 类来创建自定义滤镜。

概述

GPUPixel 的滤镜系统基于 OpenGL 着色器构建。每个滤镜都继承自基础 Filter 类,并通过着色器程序实现特定的图像处理效果。

基本结构

一个典型的自定义滤镜类具有以下结构:

cpp
class CustomFilter : public Filter {
 public:
  static std::shared_ptr<CustomFilter> Create();
  bool Init();
  virtual bool DoRender(bool updateSinks = true) override;

  // 自定义参数设置器
  void setParameter(float value);

 protected:
  CustomFilter(){};

  // 滤镜参数
  float _parameter;
};

实现步骤

1. 创建工厂方法

实现一个静态工厂方法来创建和初始化滤镜:

cpp
std::shared_ptr<CustomFilter> CustomFilter::Create() {
  auto ret = std::shared_ptr<CustomFilter>(new CustomFilter());
  gpupixel::GPUPixelContext::GetInstance()->SyncRunWithContext([&] {
    if (ret && !ret->Init()) {
      ret.reset();
    }
  });
  return ret;
}

2. 初始化滤镜

实现 Init() 方法来设置着色器程序和注册参数:

cpp
bool CustomFilter::Init() {
  // 使用着色器字符串初始化
  if (!InitWithFragmentShaderString(kCustomFragmentShader)) {
    return false;
  }

  // 注册参数
  _parameter = 1.0f;
  RegisterProperty(
      "parameter",
      _parameter,
      "参数描述",
      [this](float& value) { setParameter(value); });

  return true;
}

3. 定义着色器程序

为滤镜效果创建 GLSL 着色器程序:

cpp
const std::string kCustomFragmentShader = R"(
    precision highp float;
    uniform sampler2D inputImageTexture;
    uniform float parameter;
    varying highp vec2 textureCoordinate;

    void main() {
      // 在此实现滤镜效果
      vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
      gl_FragColor = textureColor;
    })"

4. 实现处理逻辑

重写 DoRender() 方法来更新着色器 uniform 变量并处理图像:

cpp
bool CustomFilter::DoRender(bool updateSinks) {
  // 更新着色器 uniform 变量
  filter_program_->SetUniformValue("parameter", _parameter);
  
  // 调用基类实现
  return Filter::DoRender(updateSinks);
}

示例:HueFilter

这是一个调整图像色相的 HueFilter 实际示例:

cpp
class HueFilter : public Filter {
 public:
  static std::shared_ptr<HueFilter> Create();
  bool Init();
  virtual bool DoRender(bool updateSinks = true) override;

  void setHueAdjustment(float hueAdjustment);

 protected:
  HueFilter(){};
  float _hueAdjustment;
};

HueFilter 展示了:

  • 带回调的参数注册
  • DoRender() 中的着色器 uniform 更新
  • 参数设置器中的值转换

最佳实践

  1. 参数管理

    • 使用有意义的参数名称
    • 提供清晰的参数描述
    • 实现适当的值验证
  2. 着色器优化

    • 保持着色器简单高效
    • 使用适当的精度限定符
    • 考虑性能影响
  3. 错误处理

    • 检查初始化是否成功
    • 验证参数值
    • 处理资源清理

参见

基于 Apache-2.0 License 许可发布