创建时间: 2025-11-25最后更新: 2025-12-22作者: yangbo(96862973d)

Table of Contents

1概述

feColorMatrix 元素用于将图像的像素值进行矩阵变换.

颜色矩阵是一个 5x4 的矩阵, 我们可以用上面这个工具来方便大家生成理想的颜色变换矩阵.

其中第一行是红色通道, 第二行是绿色通道, 第三行是蓝色通道, 第四行是透明度通道.

[r1r2r3r4r5g1g2g3g4g5b1b2b3b4b5a1a2a3a4a5]\begin{bmatrix} r1 & r2 & r3 & r4 & r5 \\ g1 & g2 & g3 & g4 & g5 \\ b1 & b2 & b3 & b4 & b5 \\ a1 & a2 & a3 & a4 & a5 \\ \end{bmatrix}

如下所示, 我用案例表明了每一层颜色矩阵的取值.

index.html
1
<!-- 此时表示保留原图, 啥都不变 -->
2
<feColorMatrix type="matrix" values="
3
1 0 0 0 0 <!-- 红色通道:原图的红色组成部分 -->
4
0 1 0 0 0 <!-- 绿色通道:原图的绿色组成部分 -->
5
0 0 1 0 0 <!-- 蓝色通道:原图的蓝色组成部分 -->
6
0 0 0 1 0" <!-- Alpha通道:原图的透明度组成部分 -->
7
/>

矩阵乘法公式为

[rgba]=[r1r2r3r4r5g1g2g3g4g5b1b2b3b4b5a1a2a3a4a5]X[RGBA1]\begin{bmatrix} r` \\ g` \\ b` \\ a` \\ \end{bmatrix} = \begin{bmatrix} r1 & r2 & r3 & r4 & r5 \\ g1 & g2 & g3 & g4 & g5 \\ b1 & b2 & b3 & b4 & b5 \\ a1 & a2 & a3 & a4 & a5 \\ \end{bmatrix} X \begin{bmatrix} R \\ G \\ B \\ A \\ 1 \end{bmatrix}

翻译一下就是:

  • 新的红色通道 = (旧红色 x r1) + (旧绿色 x r2) + (旧蓝色 x r3) + (旧透明度 x r4) + (偏移量 r5)
  • 新的绿色通道 = (旧红色 x g1) + (旧绿色 x g2) + (旧蓝色 x g3) + (旧透明度 x g4) + (偏移量 g5)
  • 新的蓝色通道 = (旧红色 x b1) + (旧绿色 x b2) + (旧蓝色 x b3) + (旧透明度 x b4) + (偏移量 b5)
  • 新的透明度通道 = (旧红色 x a1) + (旧绿色 x a2) + (旧蓝色 x a3) + (旧透明度 x a4) + (偏移量 a5)

feColorMatrix 主要通过 type 属性来定义不同的颜色操作模式

  • matrix 完整的矩阵变换模式, 可以通过该方法来实现最精确的颜色控制
  • saturate 饱和度模式, 取值范围 0 ~ 1, 0 表示完全去色, 1 表示完全不改变
  • hueRotate 色相旋转模式, 用于调整图像的色相, 取值范围 0 ~ 360, 0 表示完全不改变, 360 表示完全旋转一圈
  • luminanceToAlpha 亮度到透明度模式, 用于将图像的亮度转换为透明度, 取值范围 0 ~ 1, 0 表示完全透明, 1 表示完全不透明

饱和度、色相旋转、透明度的表现与 css filter 的表现与取值都是一致的, 因此我们这里不再使用案例来演示, 我们主要学习 matrix 模式.

我们通过如下案例来感受不同的颜色操作模式

预览
index.tsx
01
{/* 只保留红色通道 */}
02
<filter id="92demo01_matrix_red">
03
<feColorMatrix type="matrix" values="
04
1 0 0 0 0
05
0 0 0 0 0
06
0 0 0 0 0
07
0 0 0 1 0"
08
/>
09
</filter>
10
11
{/* 只保留绿色通道 */}
12
<filter id="92demo01_matrix_green">
13
<feColorMatrix type="matrix" values="
14
0 0 0 0 0
15
0 1 0 0 0
16
0 0 0 0 0
17
0 0 0 1 0"
18
/>
19
</filter>
20
21
{/* 只保留蓝色通道 */}
22
<filter id="92demo01_matrix_blue">
23
<feColorMatrix type="matrix" values="
24
0 0 0 0 0
25
0 0 0 0 0
26
0 0 1 0 0
27
0 0 0 1 0"
28
/>
29
</filter>

2实践:spotify 风格

Spotify 双色调风格是一种适合品牌化的风格. 我们可以使用 2 次颜色转换来实现该效果.

首先将原图转为灰色, 然后将高光映射会另外一种颜色:例如亮粉、荧光绿、深紫色等. 从而让多张图片呈现出统一的风格.

预览
index.html
01
<svg width="0" height="0" style="position: absolute;">
02
<filter id="92demo03_matrix_spotify">
03
<!-- 步骤1: 将图片转为灰度, 但为了保留细节, 我们混合RGB通道 -->
04
<feColorMatrix type="matrix" result="gray" values="
05
1 0 0 0 0
06
1 0 0 0 0
07
1 0 0 0 0
08
0 0 0 1 0" />
09
10
<!-- 步骤2: 颜色映射
11
我们将灰度值映射到两个特定颜色:
12
颜色A (深紫): R:44 G:20 B:180 (#2c14b4)
13
颜色B (荧光粉): R:255 G:55 B:160 (#ff37a0)
14
原理:利用最后一列作为基础色(暗部), 利用前三列作为增量(亮部)
15
-->
16
<feColorMatrix type="matrix" in="gray" values="
17
0.82 0 0 0 0.17
18
0.13 0 0 0 0.07
19
-0.07 0 0 0 0.70
20
0 0 0 1 0" />
21
</filter>
22
</svg>

3实践:高斯模糊液态融合

在前面, 我们学习了 css 的高斯模糊与对比度增强的结合可是实现液态融合效果. 但是那种方案只能应用于简单的场景, 颜色与预期的颜色不一致, 会因为对比度增强导致颜色失真.

因此, 我们这里需要使用 feColorMatrix 来实现更精确的颜色控制.

具体的原理在备注中注明, 大家可以结合代码与备注进行理解.

预览
index.html
01
<svg width="0" height="0" style="position: absolute;">
02
<filter id="92demo04_matrix_gooey">
03
<!-- 1. 高斯模糊 -->
04
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
05
<!-- 2. Alpha 对比度增强 -->
06
<!--
07
a_4 (18): 放大 Alpha 值 (让模糊部分变清晰)
08
a_5 (-7): 减去偏移量 (切掉太淡的边缘)
09
公式: A' = A * 18 - 7
10
-->
11
<feColorMatrix in="blur" type="matrix" values="
12
1 0 0 0 0
13
0 1 0 0 0
14
0 0 1 0 0
15
0 0 0 18 -7" result="goo" />
16
<!-- 3. (可选) 将原图叠在上面, 保证内容清晰 -->
17
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
18
</filter>
19
</svg>

4实践:自定义颜色

这里分享的一个案例是利用滤镜给白底黑字的扫描件或图标上色. 详细原理请看备注

预览
index.tsx
01
<svg width="0" height="0">
02
<filter id="92demo05_matrix">
03
{/*
04
反转 Alpha:
05
让原来的白色变透明, 黑色变实体.
06
这对于处理白底黑字的扫描件或图标非常有用.
07
A' = A * -1 + 1
08
*/}
09
<feColorMatrix type="matrix" values="
10
1 0 0 0 0
11
0 1 0 0 0
12
0 0 1 0 0
13
-1 0 0 1 0"
14
/>
15
16
{/* 给实体部分上色 (例如变成深红色) */}
17
<feColorMatrix type="matrix" values="
18
0 0 0 0 0.8
19
0 0 0 0 0.1
20
0 0 0 0 0.1
21
0 0 0 1 0"
22
/>
23
</filter>
24
</svg>

如果你的图片不是纯色的黑白, 又灰色过渡, 可以使用 亮度权重 来计算, 从而使边缘更平滑

下面的变换矩阵是将上面案例中的矩阵合二为一, 可以得到同样的效果, 拆分是为了更好的理解. 你也可以在最开始的颜色编辑器中, 调出最适合你图片的变换矩阵.

index.tsx
01
<svg width="0" height="0" style="position: absolute;">
02
<filter id="text-mask-smooth">
03
<feColorMatrix type="matrix" values="
04
0 0 0 0 0.8
05
0 0 0 0 0.1
06
0 0 0 0 0.1
07
-0.21 -0.72 -0.07 1 0 "
08
/>
09
</filter>
10
</svg>
0
专栏首页
到顶
专栏目录