前言
上一篇文章中介绍了什么是滤镜、滤镜的容器和最常见的高斯滤镜及其基本应用。这篇文章将介绍几个常用的滤镜 feImage、feFlood、feOffset、feDropShadow、feColorMatrix。结合示例,来详细说明每个滤镜的使用方法。
往期文章
feImage 获取图像数据作为输出
feImage滤镜从外部来源取得图像数据,并提供像素数据作为输出(意味着如果外部来源是一个SVG图像,这个图像将被栅格化。)
属性:
xlink:href:图像的地址 preserveAspectRatio: 图像的缩放的表现模式
例:引入外部图片与外部 SVG 图像
<svg width="200" height="200" viewBox="0 0 200 200">
<defs>
<filter id="image">
<!-- feImage 引入外部图片 -->
<feImage xlink:href="../../image/VIP.png"/>
</filter>
<filter id="image2">
<!-- feImage 引入外部 svg -->
<feImage xlink:href="../../static/PPT.svg#ppt"/>
</filter>
</defs>
<rect x="10" y="10" width="80" height="80" fill="green" filter="url(#image)" />
<rect x="10" y="100" width="80" height="80" fill="green" filter="url(#image2)" />
</svg>
两者差别不大,需要注意的是引入 svg 需要指定 svg 容器 id
preserveAspectRatio 图像的缩放的表现模式
在一个容器中展示某个图片或者内容是,如果容器大小不够,无法完整的放置想要展示的内容,这个时候可以通过设置这个属性来告诉容器改如何展示内容。
preserveAspectRatio 是一个符合属性,需要指定 对齐方式 和 缩放模式
对齐方式
- none
- xMinYMin
- xMidYMin
- xMaxYMin
- xMinYMid
- xMidYMid (默认值)
- xMaxYMid
- xMinYMax
- xMidYMax
- xMaxYMax
看起来很多其实并不难,这里其实就是指定了图片的位置。换个说法就会发现非常简单
- none: 不进行统一缩放,图片会按容器大小被拉伸
- xMin:水平方向左对齐
- xMid:水平方向居中
- xMax:水平方向右对齐
- YMin:竖直方向顶部对齐
- YMid:竖直方向居中
- YMax: 竖直方向底部对齐
举几个例子
xMinYMin:水平方向左对齐,竖直方向顶部对齐。所以图片会在左上角 xMaxYMid:水平方向右对齐,竖直方向居中。所以图片会靠右侧竖直居中
缩放模式
- meet: 展示内容部分会优先占满短边进行等比缩放,会尽可能完整的展示内容。
- slice:展示内容部分会优先占满长边进行等比缩放,展示内容可能展示不完全,会超出容器
全部情况的展示对比
具体的代码比较多,最后会在整个系列整理完成之后统一开源。留给有缘人。
feFlood 指定滤镜的填充
属性:
- flood-color: 填充的颜色
- flood-opacity: 填充的透明度
简单使用:
.border{
display: inline-block;
border: 1px solid #000;
}
.img {
display: block;
width: 100px;
height: 100px;
}
.filter-svg{
filter: url("#MyFilter");
}
<svg width="100" height="100" viewBox="0 0 100 100">
<defs>
<filter id="MyFilter">
<feFlood x="0" y="0" flood-color="green" flood-opacity="0.5"/>
</filter>
</defs>
<!-- 通过滤镜给矩形添加填充 -->
<rect x="10" y="10" width="80" height="80" filter="url(#MyFilter)" />
</svg>
<!-- 这里滤镜的填充图形替换了原有的图片内容 -->
<img src="../../image/VIP.png" class="img filter-svg" alt="" />
feOffset 指定输入图像的偏移量
属性:
- in:数据输入源
- dx:x方向上的偏移量
- dy:y方向上的偏移量
简单使用
<svg class="border" width="200" height="200" viewBox="0 0 200 200" style="display: none;">
<defs>
<filter id="MyFilter" >
<feOffset in="SourceGraphic" dx="20" dy="20" />
</filter>
<filter id="MyFilter2" >
<!-- in 可以不传,默认为 SourceGraphic -->
<feOffset dx="20" dy="20" />
</filter>
</defs>
</svg>
<div class="border">
<img src="../../image/VIP.png" alt="" style="filter: url(#MyFilter);">
</div>
<div class="border">
<img src="../../image/VIP.png" alt="" style="filter: url(#MyFilter2);">
</div>
feDropShadow 图像投影
该滤镜对输入图像进行投影。所以透明的不会被投射出来。其结果同 css 滤镜中的 drop-shadow。
属性:
- dx: 此属性定义投影的 x 偏移量。
- dy: 此属性定义投影的 y 偏移量。
- stdDeviation: 定义模糊操作的标准差,值越大越模糊。20以上基本上就看不到了
- flood-color: 投影的颜色(feFlood,的专有属性,在此也可以使用)
- flood-opacity: 投影的透明度(feFlood,的专有属性,在此也可以使用)
简单使用
<svg width="100" height="100" viewBox="0 0 100 100">
<defs>
<filter id="dropShadow">
<feDropShadow dx="8" dy="8" flood-color="red" flood-opacity="0.5" stdDeviation="2" />
</filter>
</defs>
</svg>
<img src="../../image/处女座.png" class="img filter-svg" alt="" />
feColorMatrix 图像矩阵变换
该滤镜基于转换矩阵对颜色进行变换。每一像素的颜色值(一个表示为[红,绿,蓝,透明度] 的矢量) 都经过矩阵乘法 (matrix multiplated) 计算出的新颜色。
属性:
- type: 类型。有预设的矩阵作为特定类型可供选择,你也可以通过 matrix 来自己写矩阵函数
- values: 值。不同类型所对应的值不一致
type:saturate
改变图像的饱和度,效果同 filter: saturate
value: 标准值在 0 - 1 之间。超过 1 饱和度叠加递增
例子:
<svg>
<defs>
<filter id="saturate">
<feColorMatrix id="saturateMatrix" in="SourceGraphic" type="saturate" values="0.2"/>
</filter>
</defs>
</svg>
<h4>saturate</h4>
<img class="img saturate" src="../../image/VIP.png" alt="">
0-1之间
<input id="saturateInput" value="0.2" onchange="change(event,'saturate')" type="text">
修改 values 属性(后面的例子也有使用,就不一一列举)
function change(e,type,_value){
const value = e.target.value;
const target = document.getElementById(type + 'Matrix');
target.attributes.values.value = _value || value;
}
给图片设置滤镜(后面的例子也有使用,就不一一列举)
.img {
display: block;
width: 200px;
height: 250px;
}
.saturate{
filter: url("#saturate");
}
type:hueRotate
色环旋转,效果同 filter: hue-rotate。
value: 角度值。 同样的超过 360° 等于重新开始了一圈。
例子:
<filter id="hueRotate">
<feColorMatrix id="hueRotateMatrix" in="SourceGraphic" type="hueRotate" values="100"/>
</filter>
<h4>hueRotate</h4>
<img class="img hueRotate" src="../../image/VIP.png" alt="">
角度值
<input id="hueRotateInput" value="100" onchange="change(event,'hueRotate')" type="text">
type:luminanceToAlpha
阿尔法亮度,没有 value 值
例子
<filter id="luminanceToAlpha">
<feColorMatrix in="SourceGraphic" type="luminanceToAlpha"/>
</filter>
<h4>luminanceToAlpha</h4>
<img class="img luminanceToAlpha" src="../../image/VIP.png" alt="">
type:matrix
颜色矩阵(估计要些美术知识),像素级的绘制图像
value: 矩阵值。是一个 4 * 5 的矩阵值
R G B A 11 0 0 0 0 => R = 1*R + 0*G + 0*B + 0*A + 00 1 0 0 0 => G = 0*R + 1*G + 0*B + 0*A + 00 0 1 0 0 => B = 0*R + 0*G + 1*B + 0*A + 00 0 0 1 0 => A = 0*R + 0*G + 0*B + 1*A + 0
matrix 可以实现 feColorMatrix 其他 type 类型的效果。同时可以自己设置矩阵,以达到更丰富的效果。
原像矩阵
<filter id="matrix">
<feColorMatrix in="SourceGraphic" type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0"
/>
<div>原像矩阵</div>
<img class="img matrix" src="../../image/VIP.png" alt="">
透明
<filter id="matrix2">
<feColorMatrix in="SourceGraphic" type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 .2 0"
/>
</filter>
<div>透明</div>
<img class="img matrix2" src="../../image/VIP.png" alt="">
单色增强
<filter id="matrix3">
<feColorMatrix in="SourceGraphic" type="matrix"
values="1 0 0 0 .5
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0"
/>
</filter>
<div>单色增强(这里例子用的是红色)</div>
<img class="img matrix3" src="../../image/VIP.png" alt="">
暗色
<filter id="matrix4">
<feColorMatrix in="SourceGraphic" type="matrix"
values=".2 0 0 0 0
0 .2 0 0 0
0 0 .2 0 0
0 0 0 1 0"
/>
</filter>
<div>暗度</div>
<img class="img matrix4" src="../../image/VIP.png" alt="">
灰白
<filter id="matrix5">
<!-- 这里矩阵前面 3 x 3 的小矩阵同值就能保证最后输出的值颜色相同。 -->
<!-- 但是输出值越接近 1 图像越亮。原因就是最后的 rgb 位置的值远大于 1 所以图片太白了就显示不出东西了。所以我给了个 -0.5 的控制量看得清除点 -->
<feColorMatrix in="SourceGraphic" type="matrix"
values=".5 .5 .5 0 -0.5
.5 .5 .5 0 -0.5
.5 .5 .5 0 -0.5
0 0 0 1 0"
/>
<!-- values="1 1 1 0 0
1 1 1 0 0
1 1 1 0 0
0 0 0 1 0" -->
</filter>
<div>灰白 => rgb 同值图像变灰</div>
<img class="img matrix5" src="../../image/VIP.png" alt="">
颜色增强
<filter id="matrix6">
<feColorMatrix in="SourceGraphic" type="matrix"
values="1.2 0 0 0 0
0 1.2 0 0 0
0 0 1.2 0 0
0 0 0 1 0"
/>
</filter>
<div>颜色增强</div>
<img class="img matrix6" src="../../image/VIP.png" alt="">
颜色修改
<filter id="matrix7">
<feColorMatrix id="colorMatrix" in="SourceGraphic" type="matrix"
values="0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0"
/>
</filter>
<div>颜色修改</div>
<img class="img matrix7" src="../../image/处女座.png" alt="">
<label>红:<input type="radio" checked="checked" name="color" value="1" onchange="change(event,'color','0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0')"/></label>
<label>绿:<input type="radio" name="color" value="2" onchange="change(event,'color','0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0')"/></label>
<label>蓝:<input type="radio" name="color" value="3" onchange="change(event,'color','0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0')"/></label>
最后
参考资料