SVG滤镜feColorMatrix总结

起因

最近写了很多关于SVG滤镜的内容,但大部分都是直接呈现了一个效果,并没有去详细的记录关于各个滤镜的详细用法,这次想换个写作风格也是给自己留个备忘录~

往期SVG滤镜相关内容

feColorMatrix

<feColorMatrix> 是 SVG 滤镜中的一个元素,用于对图形的颜色值进行转换和调整。它通过 5x4 的矩阵操作,对每个像素的红色 (R)、绿色 (G)、蓝色 (B) 和透明度 (A) 进行重新计算,从而实现各种颜色效果,如色调旋转、灰度化、饱和度调整等。

python 复制代码
| R' |     | r1 r2 r3 r4 r5 |   | R |
| G' |     | g1 g2 g3 g4 g5 |   | G |
| B' |  =  | b1 b2 b3 b4 b5 | * | B |
| A' |     | a1 a2 a3 a4 a5 |   | A |

计算公式可以展开为:

  • R' = r1 * R + r2 * G + r3 * B + r4 * A + r5
  • G' = g1 * R + g2 * G + g3 * B + g4 * A + g5
  • B' = b1 * R + b2 * G + b3 * B + b4 * A + b5
  • A' = a1 * R + a2 * G + a3 * B + a4 * A + a5

矩阵中的值决定了颜色的最终效果。

属性说明

  1. type 属性

    定义矩阵的类型,常见值包括:

    • matrix:手动指定矩阵值。
    • saturate:调整饱和度。
    • hueRotate:旋转色相。
    • luminanceToAlpha:将亮度值转换为透明度值。
  2. values 属性

    当 type="matrix" 时,用于指定 5x4 的矩阵值。值用空格或逗号分隔。

saturate

saturate变换会影响图像中每个像素的颜色强度(从灰度到全彩)。feColorMatrixsaturate 功能通过指定 values 属性来设定饱和度的值。

  • values="1" 表示图像保持原样,即饱和度没有变化。
  • values="0" 会将图像变成完全灰度(无饱和度,所有颜色都转为灰色)。
  • values > 1 会增加图像的饱和度,使颜色更加鲜艳。
  • values < 0 会反向饱和(通常结果类似于反转色彩)。

可以拖拽saturate查看效果

hueRotate

色相旋转通过改变颜色在色轮上的位置来调整颜色。例如红色可能会变成蓝色或绿色蓝色可能会变成绿色或红色

  • values="0" 表示不旋转,图像保持原样。
  • values="90" 将色相旋转 90°。
  • values="180" 将色相旋转 180°,通常会反转颜色。
  • values="360" 等价于不旋转(颜色循环一圈回到原点)。

可以拖拽hueRotate查看效果

luminanceToAlpha

feColorMatrix 中的 luminanceToAlpha 是一个特殊的类型,它将图像的亮度信息(即每个像素的光亮程度)转换为透明度信息(Alpha 通道)

这个属性可谓是最难理解的属性之一了,光看定义完全无法理解,还是看个例子先!

luminanceToAlpha不接受value,也不受R、G、B影响只受亮度影响,其中亮度(Luminance)的算法是
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> L u m i n a n c e = 0.2126 × R + 0.7152 × G + 0.0722 × B Luminance=0.2126×R+0.7152×G+0.0722×B </math>Luminance=0.2126×R+0.7152×G+0.0722×B

  • 亮度较高的区域会被映射的更接近不透明也可以理解成黑色
  • 亮度较低的区域会映射为较低的 Alpha 值,即更加透明。

luminanceToAlpha常常会配合其他滤镜一起使用,这里先不过多的展开🤖,知道这个属性的功能效果先~

matrix

matrix是整个feColorMatrix中最重要的属性,上述介绍的其他属性都可以通过matrix来实现!

<feColorMatrix> 中的 type="matrix" 是一种通过矩阵操作来修改图像颜色和透明度的方式。这种方法可以直接对图像的颜色通道进行数学运算,改变每个像素的颜色值。与其他类型的 feColorMatrix(如 saturate 或 hueRotate)相比,matrix 提供了更大的灵活性,允许开发者自定义颜色转换的具体方式。

matrix 采用的是一个 4x5 的矩阵结构,矩阵的每一行与颜色的 R、G、B 和 A 分量相对应,最后一列是一个额外的偏移值,具体的公式如下
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> R ′ = ( R × m 11 ) + ( G × m 12 ) + ( B × m 13 ) + ( A × m 14 ) + m 15 G ′ = ( R × m 21 ) + ( G × m 22 ) + ( B × m 23 ) + ( A × m 24 ) + m 25 B ′ = ( R × m 31 ) + ( G × m 32 ) + ( B × m 33 ) + ( A × m 34 ) + m 35 A ′ = ( R × m 41 ) + ( G × m 42 ) + ( B × m 43 ) + ( A × m 44 ) + m 45 R' = (R \times m_{11}) + (G \times m_{12}) + (B \times m_{13}) + (A \times m_{14}) + m_{15} \\ G' = (R \times m_{21}) + (G \times m_{22}) + (B \times m_{23}) + (A \times m_{24}) + m_{25} \\ B' = (R \times m_{31}) + (G \times m_{32}) + (B \times m_{33}) + (A \times m_{34}) + m_{35} \\ A' = (R \times m_{41}) + (G \times m_{42}) + (B \times m_{43}) + (A \times m_{44}) + m_{45} </math>R′=(R×m11)+(G×m12)+(B×m13)+(A×m14)+m15G′=(R×m21)+(G×m22)+(B×m23)+(A×m24)+m25B′=(R×m31)+(G×m32)+(B×m33)+(A×m34)+m35A′=(R×m41)+(G×m42)+(B×m43)+(A×m44)+m45

这里,m_{ij} 代表矩阵中的元素,而 R, G, B, A 是图像的每个像素的颜色通道值,并且矩阵中的输入颜色值是归一化到 0~1 的浮点数范围内,而不是直接使用 0~255 的整数范围。这种归一化的方式适用于所有输入的 RGB 和 Alpha 通道值。

举一个例子!

html 复制代码
.box {
        width: 400px;
        height: 400px;
        background: rgba(255, 0, 0, 1);
        filter: url(#matrix);
}

...
...

<svg>
    <filter id="matrix">
        <feColorMatrix type="matrix" values="
                1 0 0 0 0
                0 1 0 0 0
                0 0 1 0 0
                0 0 0 1 0"/>
    </filter>
</svg>

带入到公式中
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 1 = ( 1 × 1 ) + ( 0 × 0 ) + ( 0 × 0 ) + ( 1 × 0 ) + 0 0 = ( 1 × 0 ) + ( 0 × 1 ) + ( 0 × 0 ) + ( 1 × 0 ) + 0 0 = ( 1 × 0 ) + ( 0 × 0 ) + ( 0 × 1 ) + ( 1 × 0 ) + 0 1 = ( 1 × 0 ) + ( 0 × 0 ) + ( 0 × 0 ) + ( 1 × 1 ) + 0 1 = (1 \times 1) + (0 \times 0) + (0 \times 0) + (1 \times 0) + 0 \\ 0 = (1 \times 0) + (0 \times 1) + (0 \times 0) + (1 \times 0) + 0 \\ 0 = (1 \times 0) + (0 \times 0) + (0 \times 1) + (1 \times 0) + 0 \\ 1 = (1 \times 0) + (0 \times 0) + (0 \times 0) + (1 \times 1) + 0 \\ </math>1=(1×1)+(0×0)+(0×0)+(1×0)+00=(1×0)+(0×1)+(0×0)+(1×0)+00=(1×0)+(0×0)+(0×1)+(1×0)+01=(1×0)+(0×0)+(0×0)+(1×1)+0

最终输出结果会重新映射到 0 ~ 255 的整数范围
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> R = 1 = 255 , G = 0 = 0 , B = 0 = 0 , A = 1 = 255 R = 1 = 255, \quad G = 0 = 0, \quad B = 0 = 0, \quad A = 1 = 255 </math>R=1=255,G=0=0,B=0=0,A=1=255

这个矩阵保证了所有颜色通道依然保持原有的色值,所以上述例子中的红色矩形最终依然保持了红色!

如果我们想让红色的矩形变成绿色,只需要让红色通道最终结果为0,绿色通道最终结果为1

html 复制代码
 <feColorMatrix type="matrix" values="
                0 0 0 0 0  👈红色通道最后结果全部为0
                0 1 0 0 1  👈绿色通道最终偏移加上1也就是255
                0 0 1 0 0
                0 0 0 1 0"/>

效果展示

利用matrix我们可以完成很多有意思的效果

灰度展示

ini 复制代码
 <feColorMatrix type="matrix" values="
               0.2126 0.7152 0.0722 0 0
               0.2126 0.7152 0.0722 0 0
               0.2126 0.7152 0.0722 0 0
               0      0      0      1 0"/>

灰度看腻了?我们把红色通道的权重修改一下再看看效果~

这也突显了matrix的自由,可以任意配置数值改变原图~

去色(黑白)

html 复制代码
values="
  0.33 0.33 0.33 0 0
  0.33 0.33 0.33 0 0
  0.33 0.33 0.33 0 0
  0    0    0    1 0"

降低亮度

html 复制代码
values="
  1 0 0 0 -0.2
  0 1 0 0 -0.2
  0 0 1 0 -0.2
  0 0 0 1 0"

色相转换

html 复制代码
values="
  0  1  0  0 0
  0  0  1  0 0
  1  0  0  0 0
  0  0  0  1 0"

将原来的 RGB 值重新排列:R → G,G → B,B → R,形成色相旋转。

粘滞效果

这个技巧在H5 实现超丝滑ChatGPT语音交互中有使用到过

html 复制代码
<svg width="400" height="400">
   
    <defs>
        <filter id="goo">
            <feGaussianBlur stdDeviation="15"></feGaussianBlur>
            <feColorMatrix type="matrix" values="
                                         1 0 0 0 0
                                         0 1 0 0 0
                                         0 0 1 0 0
                                         0 0 0 26 -7">
            </feColorMatrix>
        </filter>
    </defs>

    <g filter="url(#goo)">
        <circle cx="200" cy="200" r="20" fill="white"></circle>
        <circle cx="300" cy="200" r="20" fill="white">
            <animate
                    attributeName="cx"
                    from="300"
                    to="100"
                    dur="4s"
                    repeatCount="indefinite"/>
        </circle>
    </g>

</svg>

字体背景圆角效果

html 复制代码
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <filter id="goo">
            <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
            <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" result="goo" />
            <feComposite in="SourceGraphic" in2="goo" operator="atop"/>
        </filter>
    </defs>
</svg>

效果来自Gooey text background with SVG filters

结束语

关于feColorMatrix相关内容就先到这里啦,喜欢的朋友点点关注~

相关推荐
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte6 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc