feComponentTransfer 是 SVG 滤镜中通过逐像素重映射 R/G/B/A 通道值实现精细色调控制的底层工具,支持 identity、table、discrete、linear、gamma 五种映射方式,常用于胶片暖调、青橙色调分离等 CSS filter 难以实现的效果。

feComponentTransfer 是 SVG 滤镜中控制色调最精细、最底层的工具之一。它不靠矩阵运算,而是直接对每个颜色通道(R/G/B/A)的输入值做逐像素映射,因此能实现精确的色调偏移、胶片感调色、高光/阴影独立压暗或提亮等 CSS filter 难以复现的效果。
理解 feComponentTransfer 的工作逻辑
它本身不生成新像素,而是重映射已有像素的通道值。核心是四个子元素:feFuncR、feFuncG、feFuncB、feFuncA,每个负责一个通道。每个子元素通过 type 属性决定映射方式,常见取值有:
- identity:直通,不做任何改变
- table:按分段线性插值映射,适合平滑调整亮度曲线
- discrete:阶梯式映射,可模拟复古扫描线、胶片颗粒感
- linear:y = slope × x + intercept,适合整体提亮/压暗或对比度微调
- gamma:y = xexponent,天然适配人眼感知,常用于 gamma 校正或柔和色调压缩
用 table 实现胶片暖调(红/黄通道强化)
想让图像在保持自然的前提下略带暖意,可只增强红色与绿色通道的中高光区域,同时抑制蓝色通道的高光溢出:
<feFuncR type="table" tableValues="0.0 0.2 0.6 0.95 1.0"/> <feFuncG type="table" tableValues="0.0 0.15 0.5 0.9 1.0"/> <feFuncB type="table" tableValues="0.0 0.1 0.3 0.7 0.85"/>
这里用了 5 个 tableValues,将原始 [0,1] 输入划分为 4 段;每段输出值非均匀递增,使中间调更饱满、高光更柔和——这正是胶片扫描常见的“S型曲线”雏形。
用 linear + gamma 组合做精准色调分离
要实现类似“青橙色调”(阴影偏青、高光偏橙),不能只调 RGB,需先分离明暗区域。常用做法是:
- 用 feColorMatrix 提取亮度通道(luminanceToAlpha)
- 用 feComponentTransfer 对 alpha(即亮度)做 linear 映射,生成“暗部掩模”和“亮部掩模”
- 再用 feComposite 将不同色调的着色层分别叠加到对应掩模上
例如,让亮度低于 0.3 的像素统一染青(Cyan),高于 0.7 的染橙(Orange),中间过渡自然,就依赖于 feFuncA 的 linear 分段控制能力。
注意 color-interpolation-filters 色彩空间的影响
feComponentTransfer 的计算结果会受 filter 元素上的 color-interpolation-filters 属性影响:
- 设为 sRGB(默认):映射基于人眼习惯的非线性响应,调色直观,适合 UI 和设计稿
- 设为 linearRGB:所有计算在线性光空间进行,gamma 值变化更物理准确,适合影视级调色或与 WebGL 渲染管线对齐
同一组 tableValues 在两种模式下输出的视觉效果可能明显不同,尤其在暗部细节和高光过渡处。建议调试时显式声明该属性,避免跨浏览器差异。


















