feColorMatrix 元素用于将图像的像素值进行矩阵变换。
颜色矩阵是一个 5x4 的矩阵,我们可以用上面这个工具来方便大家生成理想的颜色变换矩阵。
其中第一行是红色通道,第二行是绿色通道,第三行是蓝色通道,第四行是透明度通道。
如下所示,我用案例表明了每一层颜色矩阵的取值。
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/>
矩阵乘法公式为
翻译一下就是:
feColorMatrix 主要通过 type 属性来定义不同的颜色操作模式
matrix 完整的矩阵变换模式,可以通过该方法来实现最精确的颜色控制saturate 饱和度模式,取值范围 0 ~ 1,0 表示完全去色,1 表示完全不改变hueRotate 色相旋转模式,用于调整图像的色相,取值范围 0 ~ 360,0 表示完全不改变,360 表示完全旋转一圈luminanceToAlpha 亮度到透明度模式,用于将图像的亮度转换为透明度,取值范围 0 ~ 1,0 表示完全透明,1 表示完全不透明饱和度、色相旋转、透明度的表现与 css filter 的表现与取值都是一致的,因此我们这里不再使用案例来演示,我们主要学习 matrix 模式。
我们通过如下案例来感受不同的颜色操作模式
10{/* 只保留红色通道 */}20<filter id="92demo01_matrix_red">30<feColorMatrix type="matrix" values="401 0 0 0 0500 0 0 0 0600 0 0 0 0700 0 0 1 0"80/>90</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 次颜色转换来实现该效果。
首先将原图转为灰色,然后将高光映射会另外一种颜色:例如亮粉、荧光绿、深紫色等。从而让多张图片呈现出统一的风格。
10<svg width="0" height="0" style="position: absolute;">20<filter id="92demo03_matrix_spotify">30<!-- 步骤1: 将图片转为灰度,但为了保留细节,我们混合RGB通道 -->40<feColorMatrix type="matrix" result="gray" values="501 0 0 0 0601 0 0 0 0701 0 0 0 0800 0 0 1 0" />9010<!-- 步骤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 来实现更精确的颜色控制。
具体的原理在备注中注明,大家可以结合代码与备注进行理解。
10<svg width="0" height="0" style="position: absolute;">20<filter id="92demo04_matrix_gooey">30<!-- 1. 高斯模糊 -->40<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />50<!-- 2. Alpha 对比度增强 -->60<!--70a_4 (18): 放大 Alpha 值 (让模糊部分变清晰)80a_5 (-7): 减去偏移量 (切掉太淡的边缘)90公式: 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>
这里分享的一个案例是利用滤镜给白底黑字的扫描件或图标上色。详细原理请看备注
10<svg width="0" height="0">20<filter id="92demo05_matrix">30{/*40反转 Alpha:50让原来的白色变透明,黑色变实体。60这对于处理白底黑字的扫描件或图标非常有用。70A' = A * -1 + 180*/}90<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>
如果你的图片不是纯色的黑白,又灰色过渡,可以使用 亮度权重 来计算,从而使边缘更平滑
下面的变换矩阵是将上面案例中的矩阵合二为一,可以得到同样的效果,拆分是为了更好的理解。你也可以在最开始的颜色编辑器中,调出最适合你图片的变换矩阵。
10<svg width="0" height="0" style="position: absolute;">20<filter id="text-mask-smooth">30<feColorMatrix type="matrix" values="400 0 0 0 0.8500 0 0 0 0.1600 0 0 0 0.170-0.21 -0.72 -0.07 1 0 "80/>90</filter>10</svg>