feColorMatrix 元素用于将图像的像素值进行矩阵变换.
颜色矩阵是一个 5x4 的矩阵, 我们可以用上面这个工具来方便大家生成理想的颜色变换矩阵.
其中第一行是红色通道, 第二行是绿色通道, 第三行是蓝色通道, 第四行是透明度通道.
r1g1b1a1r2g2b2a2r3g3b3a3r4g4b4a4r5g5b5a5如下所示, 我用案例表明了每一层颜色矩阵的取值.
1<!-- 此时表示保留原图, 啥都不变 -->2<feColorMatrix type="matrix" values="31 0 0 0 0 <!-- 红色通道:原图的红色组成部分 -->40 1 0 0 0 <!-- 绿色通道:原图的绿色组成部分 -->50 0 1 0 0 <!-- 蓝色通道:原图的蓝色组成部分 -->60 0 0 1 0" <!-- Alpha通道:原图的透明度组成部分 -->7/>
矩阵乘法公式为
r‘g‘b‘a‘=r1g1b1a1r2g2b2a2r3g3b3a3r4g4b4a4r5g5b5a5XRGBA1翻译一下就是:
feColorMatrix 主要通过 type 属性来定义不同的颜色操作模式
matrix 完整的矩阵变换模式, 可以通过该方法来实现最精确的颜色控制saturate 饱和度模式, 取值范围 0 ~ 1, 0 表示完全去色, 1 表示完全不改变hueRotate 色相旋转模式, 用于调整图像的色相, 取值范围 0 ~ 360, 0 表示完全不改变, 360 表示完全旋转一圈luminanceToAlpha 亮度到透明度模式, 用于将图像的亮度转换为透明度, 取值范围 0 ~ 1, 0 表示完全透明, 1 表示完全不透明饱和度、色相旋转、透明度的表现与 css filter 的表现与取值都是一致的, 因此我们这里不再使用案例来演示, 我们主要学习 matrix 模式.
我们通过如下案例来感受不同的颜色操作模式
01{/* 只保留红色通道 */}02<filter id="92demo01_matrix_red">03<feColorMatrix type="matrix" values="041 0 0 0 0050 0 0 0 0060 0 0 0 0070 0 0 1 0"08/>09</filter>1011{/* 只保留绿色通道 */}12<filter id="92demo01_matrix_green">13<feColorMatrix type="matrix" values="140 0 0 0 0150 1 0 0 0160 0 0 0 0170 0 0 1 0"18/>19</filter>2021{/* 只保留蓝色通道 */}22<filter id="92demo01_matrix_blue">23<feColorMatrix type="matrix" values="240 0 0 0 0250 0 0 0 0260 0 1 0 0270 0 0 1 0"28/>29</filter>
Spotify 双色调风格是一种适合品牌化的风格. 我们可以使用 2 次颜色转换来实现该效果.
首先将原图转为灰色, 然后将高光映射会另外一种颜色:例如亮粉、荧光绿、深紫色等. 从而让多张图片呈现出统一的风格.
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="051 0 0 0 0061 0 0 0 0071 0 0 0 0080 0 0 1 0" />0910<!-- 步骤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="170.82 0 0 0 0.17180.13 0 0 0 0.0719-0.07 0 0 0 0.70200 0 0 1 0" />21</filter>22</svg>
在前面, 我们学习了 css 的高斯模糊与对比度增强的结合可是实现液态融合效果. 但是那种方案只能应用于简单的场景, 颜色与预期的颜色不一致, 会因为对比度增强导致颜色失真.
因此, 我们这里需要使用 feColorMatrix 来实现更精确的颜色控制.
具体的原理在备注中注明, 大家可以结合代码与备注进行理解.
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<!--07a_4 (18): 放大 Alpha 值 (让模糊部分变清晰)08a_5 (-7): 减去偏移量 (切掉太淡的边缘)09公式: A' = A * 18 - 710-->11<feColorMatrix in="blur" type="matrix" values="121 0 0 0 0130 1 0 0 0140 0 1 0 0150 0 0 18 -7" result="goo" />16<!-- 3. (可选) 将原图叠在上面, 保证内容清晰 -->17<feComposite in="SourceGraphic" in2="goo" operator="atop"/>18</filter>19</svg>
这里分享的一个案例是利用滤镜给白底黑字的扫描件或图标上色. 详细原理请看备注
01<svg width="0" height="0">02<filter id="92demo05_matrix">03{/*04反转 Alpha:05让原来的白色变透明, 黑色变实体.06这对于处理白底黑字的扫描件或图标非常有用.07A' = A * -1 + 108*/}09<feColorMatrix type="matrix" values="101 0 0 0 0110 1 0 0 0120 0 1 0 013-1 0 0 1 0"14/>1516{/* 给实体部分上色 (例如变成深红色) */}17<feColorMatrix type="matrix" values="180 0 0 0 0.8190 0 0 0 0.1200 0 0 0 0.1210 0 0 1 0"22/>23</filter>24</svg>
如果你的图片不是纯色的黑白, 又灰色过渡, 可以使用 亮度权重 来计算, 从而使边缘更平滑
下面的变换矩阵是将上面案例中的矩阵合二为一, 可以得到同样的效果, 拆分是为了更好的理解. 你也可以在最开始的颜色编辑器中, 调出最适合你图片的变换矩阵.
01<svg width="0" height="0" style="position: absolute;">02<filter id="text-mask-smooth">03<feColorMatrix type="matrix" values="040 0 0 0 0.8050 0 0 0 0.1060 0 0 0 0.107-0.21 -0.72 -0.07 1 0 "08/>09</filter>10</svg>