svg滤镜应用:实现图像局部模糊
<style>.ma p { margin: 8px 0; }
.rred { color: red; }
.ma > pre { padding: 16px; background: #efefef; font: normal 16px monospace; white-space: pre-wrap; word-wrap: break-word; tab-size: 4; }
</style>
<div class="ma">
<p>CSS的filter滤镜,设为 <span class="rred">filter: blur(2px);</span>,可以令整个元素模糊。注意,是整个元素!以下图片,左边是原图,右边图使用了两个像素的CSS模糊滤镜:</p>
<pre><img alt="" src="https://638183.freep.cn/638183/t23/1/timestop.png" />
<img alt="" src="https://638183.freep.cn/638183/t23/1/timestop.png" style="filter: blur(2px);" /></pre>
<p>
<img alt="" src="https://638183.freep.cn/638183/t23/1/timestop.png" />
<img alt="" src="https://638183.freep.cn/638183/t23/1/timestop.png" style="filter: blur(2px);" />
</p>
<p>有时候,出于特定需要,我们只想让图片的特定区域模糊化。这时,需要请svg滤镜出场。svg滤镜与CSS滤镜同出一源,功能大抵一致,但svg滤镜拥有更高的自由度,能对元素做出更精细的过滤。此前,我们介绍过高斯模糊滤镜 feGaussianBlur,它可以设置模糊过滤效果的起点{x,y}和宽高尺寸(width和height)。考虑如下代码:</p>
<pre><feGaussianBlur x="36" y="255" width="40" height="30" stdDeviation="5" <span class="rred">in="SourceGraphic"</span> /></pre>
<p>上面的高斯滤镜代码,它设定的模糊效果从元素的{36,255}坐标点开始,模糊宽度40px、高度30px,模糊度是5px,作用范围是整个元素。这句代码不会达到我们的预期,in="SourceGraphic" 属性的设定表明,它作用于整个过滤对象,结果是,我们可能看不到元素的真容,仅看到滤镜的样子即 40*30 的渐变灰色矩形。这是因为,in 属性的指定是整个元素,而 x、y、width、height 的设定与之相冲突。处理方法是将原图和滤镜合并起来,需要分两步走,一是改造高斯滤镜,取消 in 属性,取代它的是建立一个快照(result="mohu")留待后面调用,二是使用svg独有的合并滤镜 feMerge 和 feMergeNode 组合,将源与滤镜进行合并。请看代码:</p>
<pre><svg width="300" height="389">
<filter id="myFilter">
<feGaussianBlur x="36" y="255" width="40" height="30" stdDeviation="5" <span class="rred">result="mohu"</span> />
<span class="rred"><feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode in="mohu" />
</feMerge></span>
</filter>
<image href="https://638183.freep.cn/638183/t23/1/timestop.png" <span class="rred">filter="url(#myFilter)"</span> />
</svg></pre>
<p>feMerge 是合并滤镜父标签,feMergeNode 合并滤镜子标签,子标签通过 in 属性具体规定了源和滤镜的叠加方式,第一个合并子滤镜是整个图像,所以 in="SourceGraphic",第二个合并子滤镜是将模糊滤镜合并到源上,所以 in="mohu",换言之,feMerge 滤镜告诉浏览器,将源(in="SourceGraphic")作为底片输出,在其上叠加快照为 mohu 的模糊滤镜(result="mohu")。最后,svg的 image 标签输出图像,通过 filter="url(#myFilter)" 指定滤镜名称。效果如下:</p>
<svg width="300" height="389">
<filter id="myFilter">
<feGaussianBlur x="36" y="255" width="40" height="30" stdDeviation="5" result="mohu" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode in="mohu" />
</feMerge>
</filter>
<image href="https://638183.freep.cn/638183/t23/1/timestop.png" filter="url(#myFilter)" />
</svg>
<p>当然,实现相同的功能可能有更简洁的方式,不必如此大费周章。这里,目的是为了展示svg的细致功能,以及合并滤镜初步。关于 feMerge 合并滤镜,将来可能还会接触更多。</p>
<p>html的 img 标签 也可以调用以上svg滤镜,仅需要通过CSS绑定滤镜即可。代码和效果如下:</p>
<pre><img alt="" src="https://638183.freep.cn/638183/t23/1/timestop.png" style="width: 300px; height: 389px; <span class="rred">filter: url('#myFilter');</span>" /></pre>
<p>
<img alt="" src="https://638183.freep.cn/638183/t23/1/timestop.png" style="width: 300px; height: 389px; filter: url('#myFilter');" />
</p>
</div>
还可以局部模糊,svg厉害了。只是操作看着很繁琐啊{:4_173:} 不过,当有需要的时候,能用这个去实现,也很不错呢{:4_187:} 红影 发表于 2023-10-9 21:16
还可以局部模糊,svg厉害了。只是操作看着很繁琐啊
svg理论上不是人工写代码的 红影 发表于 2023-10-9 21:17
不过,当有需要的时候,能用这个去实现,也很不错呢
svg滤镜还是很强大的 马黑黑 发表于 2023-10-9 22:45
svg理论上不是人工写代码的
难道是计算机自己写代码? 马黑黑 发表于 2023-10-9 22:45
svg滤镜还是很强大的
是啊,想滤哪就滤哪{:4_173:} 红影 发表于 2023-10-10 11:15
是啊,想滤哪就滤哪
最主要的,滤镜协同使用的情形很多,这样才能营造出纷繁复杂的效果 红影 发表于 2023-10-10 11:15
难道是计算机自己写代码?
软件 马黑黑 发表于 2023-10-10 12:51
最主要的,滤镜协同使用的情形很多,这样才能营造出纷繁复杂的效果
这个肯定很复杂{:4_173:} 马黑黑 发表于 2023-10-10 12:51
软件
软件就和那些插件的作用差不多吧,可以按需要直接得到结果的{:4_173:} 红影 发表于 2023-10-10 14:16
这个肯定很复杂
抽象而复杂 红影 发表于 2023-10-10 14:17
软件就和那些插件的作用差不多吧,可以按需要直接得到结果的
你用过类似于PS相关的软件,svg同样有类似的,其中有一个就是做PS那个公司做的,目前市场占有率是37%,是老大。开源、免费的也不少,功能也未必弱于商用软件。 马黑黑 发表于 2023-10-10 19:25
你用过类似于PS相关的软件,svg同样有类似的,其中有一个就是做PS那个公司做的,目前市场占有率是37%,是 ...
对这个不是很了解,还是黑黑厉害,连它的市场占有率都这么清楚{:4_204:} 马黑黑 发表于 2023-10-10 19:21
抽象而复杂
可能,记住需要用的单词,就会好很多吧。 红影 发表于 2023-10-10 21:32
可能,记住需要用的单词,就会好很多吧。
单词不是个事 红影 发表于 2023-10-10 21:31
对这个不是很了解,还是黑黑厉害,连它的市场占有率都这么清楚
做俺这门生意,要无所不知 马黑黑 发表于 2023-10-10 22:07
单词不是个事
记住了用在哪的,会好一些吧。 马黑黑 发表于 2023-10-10 22:08
做俺这门生意,要无所不知
厉害,佩服{:4_199:} 红影 发表于 2023-10-10 22:32
厉害,佩服
其实行行如此