Skip to content

Add SVG export for BlendImageFilter, PerlinNoise, ColorFilterShader, Luma and AlphaThreshold.#1488

Open
zfw1234567 wants to merge 67 commits into
mainfrom
feature/fengweizou_svg_imagefilter
Open

Add SVG export for BlendImageFilter, PerlinNoise, ColorFilterShader, Luma and AlphaThreshold.#1488
zfw1234567 wants to merge 67 commits into
mainfrom
feature/fengweizou_svg_imagefilter

Conversation

@zfw1234567

Copy link
Copy Markdown
Collaborator

补全 SVG 导出中此前不支持的 Filter 和 Shader 类型,并重构 filter 生成架构以支持 shader filter 和 colorFilter 的组合场景。

新增 SVG 导出支持:

ImageFilter::Blend 配合不同 shader 类型:

  • ColorShader → +
  • PerlinNoiseShader(FractalNoise / Turbulence)→ +
  • GradientShader → (内嵌带 viewBox 的渐变 SVG)+
  • ImageShader(非 DstIn 模式)→ + (支持 MatrixShader 解包定位)

ImageFilter::Compose:

  • 使用嵌套 匹配 GPU 串联管线语义

Paint Shader:

  • Shader::MakeFractalNoise / Shader::MakeTurbulence → + ,支持 baseFrequencyX/Y、numOctaves、seed、stitchTiles 全部参数
  • Shader::makeWithColorFilter → 递归解包内部 shader + 应用 colorFilter 原语

ColorFilter:

  • ColorFilter::Luma → (自定义 4×5 矩阵复现 tgfx 的 vec4(luma) 语义)
  • ColorFilter::AlphaThreshold → +
  • ColorFilter::Compose → 串联多个 filter 原语

架构改进:

  • 统一 filter 生成:当 shader(PerlinNoise/ColorFilterShader)和 brush.colorFilter 同时需要 filter 原语时,合并到单个 元素,而非互相覆盖
  • 提取 buildFilterGroupElements helper:消除 drawImage/drawLayer 中 filter group 嵌套逻辑的重复
  • BlendImageFilter 中解包 MatrixShader:支持带缩放/平移变换的 shader

Bug 修复:

  • 修复不支持的 filter 导致输出空 filter="" 属性
  • 修复 DropShadowOnly 错误使用 裁剪阴影
  • 修复 ComposeImageFilter 使用嵌套 匹配 GPU 串联管线
  • 为 Compose 链中的 shadow filter 增加软 alpha 支持:GPU 管线中 compose 链的每个子 filter 接收前一个 filter 的完整输出作为源,源边缘可能是半透明的(如模糊后的渐变边缘);若仍使用硬 alpha(将所有非零 alpha 钳位为 1),会丢失前级 filter 产生的渐变透明度导致阴影边缘不自然

测试:

  • 新增 FilterAndShaderExport 综合测试覆盖所有新类型(800×500 画布)

Comment thread include/tgfx/svg/SVGCustomWriter.h Outdated
float blurrinessY, Color color,
bool innerShadowOnly) = 0;

/**

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增的回调接口,是需要支持实际的业务支吗?没有的话先不需要加上去,并且风格应该和之前的一样,用纯虚函数。
这个也是为了支持识别filter,如果filter顺序实在不好识别,就额外写一个字段来表示filter。并且额外的字段是业务山使用的时候自己实现的

Comment thread src/svg/ElementWriter.cpp Outdated
svgFragment += " y1='" + FloatToString(info.points[0].y) + "'";
svgFragment += " x2='" + FloatToString(info.points[1].x) + "'";
svgFragment += " y2='" + FloatToString(info.points[1].y) + "'>";
} else {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

渐变分支只判断 Linear,其余类型一律走 else 当作 radialGradient 输出,存在静默错误:

  • ConicConicGradientShader::asGradient 写入 info.radiuses[0] = -bias*360(角度值),这里却当成 radial 的 r 使用 → 几何完全错误。
  • DiamondasGradient 写入的是菱形边长,同样被误用为半径。
  • Noneinfo 未被填充,输出垃圾值。

且整个过程没有任何告警。建议显式区分 Radial 分支,对 Conic/Diamond/None 调用 reportUnsupportedElement,与既有 addGradientShaderResources 的处理模式保持一致。

Comment thread src/svg/ElementWriter.cpp Outdated
Base64Encode(svgData, svgLength, base64String.data());
{
ElementWriter feImageElement("feImage", writer);
feImageElement.addAttribute("href", "data:image/svg+xml;base64," + base64String);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此处 feImage 使用裸 href,而本文件其余所有出处(如 838、1003、1475、1488 行)以及本项目自身的 SVG 解析器 SVGFeImage.cpp(仅识别 xlink:href)都使用 xlink:href。结果导出的 SVG 无法被 tgfx 自身的导入器回读,破坏往返兼容性。建议统一改为 xlink:href(或同时输出两者以兼容更广的渲染器)。

Comment thread src/svg/ElementWriter.cpp Outdated
return;
}
const auto imageShader = static_cast<const ImageShader*>(filter->shader.get());
auto data = SVGExportContext::ImageToEncodedData(imageShader->image);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这段 image→dataUri 的编码逻辑(ImageToEncodedDataIsJpeg/IsPng → 否则 ImageExportToBitmapAsDataUri)与 975 行附近的 Image shader 分支几乎完全重复,第三处 1434 行也类似。建议抽取一个 helper(如 EncodeImageToDataUri(image, context))消除重复,降低后续维护成本。

…itives matching addBlendImageFilter."

This reverts commit 51680c4.
… BlendImageFilter, ColorFilter shader, PerlinNoise shader, Luma and AlphaThreshold color filters.
…rlinNoise emission with consistent seed type.
@zfw1234567 zfw1234567 force-pushed the feature/fengweizou_svg_imagefilter branch from be41e74 to 7ec3823 Compare June 26, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants