<defs>
<filter id="id名" x="0" y="0" width="100%" height="100%" filterUnits="userSpaceOnUse">
濾鏡
</filter>
</defs>
SVG 中可用的濾鏡元件有:
<filter> 元件用於定義 SVG 濾鏡。 <filter> 元件有一個必需的 id 屬性來標識濾鏡。 然後圖形指向要使用的濾鏡。
<svg height="110" width="110">
<defs>
<filter id="f1" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation="15" />
</filter>
</defs>
<rect width="90" height="90" stroke="blue"
stroke-width="3" fill="blue" filter="url(#f1)" />
Sorry, your browser does not support inline SVG.
</svg>
<defs>
<filter id="floodFilter" filterUnits="userSpaceOnUse">
<feFlood x="50" y="50" width="100" height="100"
flood-color="green" flood-opacity="0.5"/>
</filter>
</defs>
<use style="filter: url(#floodFilter);"/>
<svg height="120" width="120">
<defs>
<filter id="f2" x="0" y="0">
<feGaussianBlur stdDeviation="5" />
<feOffset dx="5" dy="5" />
</filter>
</defs>
<rect width="90" height="90" fill="grey" filter="url(#f2)" /> // B
<rect width="90" height="90" fill="yellow" stroke="black" /> // 原始圖像
Sorry, your browser does not support inline SVG.
</svg>
<filter id="F1">
<someFilterPrimitive1 />
</filter>
<filter id="F2">
<someFilterPrimitive2 />
</filter>
<g filter="url(#F2)">
<rect height="20%" width="15%" filter="url(#F1)"/>
</g>
通過在單個
<filter id="Fs">
<someFilterPrimitive1/>
<someFilterPrimitive2/>
</filter>
<rect height="20%" width="15%" filter="url(#Fs)"/>
除了能夠順序地將不同濾鏡基元的結果鏈接在一起,其中每個連續濾鏡將前一個過濾器的輸出(稱為“result”)作為其輸入(稱為“in”), 還可以以更複雜的順序組合濾鏡。
首先,考慮濾鏡處理多種效果的預設方式。 通常, <filter> 中的第一個基元接收“SourceGraphic”作為輸入的,即濾鏡基元一一應用到的元件。
例如,如果我們定義
<rect filter=”url(#Fs)” … />那個矩形被認為是濾鏡“Fs”的 SourceGraphic。 連續的每個基元(FP1、FP2、…FPk)都將前一個濾鏡的輸出“result”當作它的輸入"in"。
<rect x="0" y="0" height="100%" width="100%" fill="white"/>
<filter id="offset" x="-20%" y="-10%" height="130%" width="240%">
<feGaussianBlur stdDeviation="10"/>
<feOffset dx="20" dy="15" result="B">
</feOffset>
<feMerge>
<feMergeNode in="B"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<g filter="url(#offset)">
<image x="25%" y="3%" xlink:href="../svg/p2.jpg" height="100%" width="100%"/>
</g>
例題:陰影動畫
<feImage xlink:href="../svg/mdn_logo_only_color.png" />
<rect x="0" y="0" height="100%" width="100%" fill="purple"/>
<filter id="T" filterUnits="objectBoundingBox" x="0" y="0"
height="100%" width="100%" >
<feImage xlink:href="p2.jpg" result="one"
x="0" y="15" width="50" height="50"/>
<feFlood x="45" y="0" width="10" height="70"
flood-color="cyan" result="two"/>
<feFlood x="25" y="18" width="50" height="10" flood-color="yellow"
flood-opacity=".5" result="three" />
<feMerge>
<feMergeNode in="one"/>
<feMergeNode in="two"/>
<feMergeNode in="three"/>
</feMerge>
<feTile/>
</filter>
<rect x="0" y="0" height="80%" width="50%" filter="url(#T)" />
| R' | | a00 a01 a02 a03 a04 | | R | | G' | | a10 a11 a12 a13 a14 | | G | | B' | = | a20 a21 a22 a23 a24 | * | B | | A' | | a30 a31 a32 a33 a34 | | A | | 1 | | 0 0 0 0 1 | | 1 |在更簡單的情況下,預定義矩陣與特殊標誌(例如“saturate”、“hueRotate”或“luminanceToAlpha”)相關聯。 這意味著可以簡單地指定標誌之一來執行指示的操作。
<svg height="440" width="440" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="F">
<feColorMatrix type="saturate" values="3" />
</filter>
</defs>
<image x="25%" y="0" width="25%" height="35%" xlink:href="p2.jpg"/>
<image x="50%" y="0" width="25%" height="35%" xlink:href="p2.jpg"
filter="url(#F)"/>
</svg>
<filter>
<feColorMatrix
type="matrix"
values="R 0 0 0 0
0 G 0 0 0
0 0 B 0 0
0 0 0 A 0 "/>
</feColorMatrix>
</filter>
每一列(row)的和就是該通道的值,最後一個值是一個乘數。
<filter id="magenta" x="0%" y="0%" width="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic"
values=
"1 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
"/>
</filter>
<image x="5%" y="0%" xlink:href="../svg/three.jpg" height="50%" width="30%"/>
<image x="5%" y="50%" xlink:href="../svg/three.jpg"
filter="url(#magenta)" height="50%" width="30%"/>
當一個顏色值消失後,會使用其他兩個值取而代之。
比如,沒有green顏色通道就會沒有white、cyan或yellow。
其實他們並沒有消失,只不過他們的亮度值(或alpha)尚未觸及。
<filter id="alpha" x="0%" y="0%" with="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic"
values=
"1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0 "/>
</filter>
<filter id="elim-blue" x="0%" y="0%" width="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic"
values=
"1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 -2 1 0
"/>
</filter>
<filter id="lighten">
<feColorMatrix type="matrix"
values="1.5 0 0 0 0
0 1.5 0 0 0
0 0 1.5 0 0
0 0 0 1 0 "/>
</filter>
<filter id="gray">
<feColorMatrix type="matrix"
values="1 0 0 0 0
1 0 0 0 0
1 0 0 0 0
0 0 0 1 0 "/>
</filter>
第一行的三個 1 移到第二或三列,也有類似效果。
<filter id="peachy">
<feColorMatrix type="matrix"
values="1 0 0 0 0
0 .5 0 0 0
0 0 0 .5 0
0 0 0 1 0 "/>
</filter>
在正常 Alpha 通道上使用紅色通道,在一半強度下應用綠色,在較暗的 Alpha 通道上應用藍色,但不在其原始顏色位置。
這種效果在陰影中為我們提供了深藍色,在高光和中間色調中混合了紅色和半綠色。
如果我們回憶一下紅色 + 綠色 = 黃色,紅色 + (綠色/2) 會更像珊瑚色。
<filter id="lime">
<feColorMatrix type="matrix"
values="1 0 0 0 0
0 2 0 0 0
0 0 0 .5 0
0 0 0 1 0 "/>
</filter>
在該段中,我們使用紅色、溢出的綠色和藍色的正常像素色調,沒有其原始色調像素,但應用於陰影中。 同樣,我們看到陰影中的深藍色,
由於紅色 + 綠色 = 黃色,紅色 + (綠色 * 2) 在高光中更像是黃綠色。
在下面的示例中,將圖像從標準 RGB 轉換為部分透明。使用圖像的最暗部分,以便底層顏色透出。 在這種情況下,使用作為濾鏡的一部分創建的“黃色”。
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="twoF" x="0%" y="0%" width="100%" height="100%">
<feFlood flood-color="yellow" result="A"/>
<feColorMatrix type="matrix" in="SourceGraphic" result="B"
values=
"1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
1 1 1 0 0
"/>
<feMerge>
<feMergeNode in="A"/>
<feMergeNode in="B"/>
</feMerge>
</filter>
<image x="5%" y="20%" xlink:href="p2.jpg" filter="url(#twoF)"
height="50%" width="30%"/>
</svg>
0 0 0
0 1 0
0 0 0
不影響任何圖像。
<filter id="edge">
<feConvolveMatrix order="3"
kernelMatrix="
-1 -1 -1
-1 7 -1
-1 -1 -1
" />
</filter>
<image id="M4" x="100" xlink:href="../svg/p2.jpg"
width="150" height="175"
filter="url(#edge)" />
上述內容誇大那些與其相鄰像素非常不同的像素,因為每個像素相鄰像素的權重為負。
浮彫示例
<defs>
<filter id="emboss">
<feConvolveMatrix order="3"
kernelMatrix="
-2 -1 0
-1 1 1
0 1 2"
edgeMode="none">
</feConvolveMatrix>
</filter>
</defs>
更多示例一:提取邊緣--浮彫
<filter id="filter1" x="0" y="0" width="100%" height="100%">
<feConvolveMatrix order="5 5" preserveAlpha="true"
kernelMatrix="
-1 0 0 0 0
0 -2 0 0 0
0 0 3 0 0
0 0 0 0 0
0 0 0 0 0" />
</filter>
更多示例二:提取邊緣--紅色浮彫
使用 feConvolveMatrix 造成浮彫效果,再用 feConvolveMatrix 僅保留紅色。
<filter id="filter1" x="0" y="0" width="100%" height="100%">
<feConvolveMatrix preserveAlpha="true"
kernelMatrix="-2 -2 -2
-2 16 -2
-2 -2 -2" />
<feColorMatrix type="matrix"
values="0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
更多示例三:提取邊緣--藍色浮彫
將 feColorMatrix 換成下列數值,即可換成僅保留藍色。
<feColorMatrix type="matrix"
values="0 0 0 0 0
0 .95 0 0 0
0 1 0 0 0
0 0 0 1 0" />
<defs>
<filter id="table">
<feComponentTransfer>
<feFuncG type="table" tableValues="0.0 0.15 0.4 1.0" />
</feComponentTransfer>
</filter>
</defs>
<image x="0" y="0" width="300" height="200" xlink:href="three.jpg" />
<image x="0" y="200" width="300" height="200"
xlink:href="three.jpg" filter="url(#green)" />
右上圖是原圖,右下圖是調整顏色後的圖像。
輸入 輸出 0-0.33 0.0-0.15 0.33-0.66 0.15-0.4 0.66-1 0.4 1.0輸入分成三等分區間,分別映對到 table 的三個區間。
色度反轉
<filter id="inverse"> <feComponentTransfer> <feFuncR type="table" tableValues="1 0" /> <feFuncG type="table" tableValues="1 0" /> <feFuncB type="table" tableValues="1 0" /> </feComponentTransfer> </filter>
<defs>
<filter id="discrete" filterUnits="userSpaceOnUse"
x="0" y="200" width="300" height="200">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0.0 1.0 1.0 1.0" />
<feFuncG type="discrete" tableValues="0.0 0.5 0.5 0.9" />
<feFuncB type="discrete" tableValues="0.0 0.6" />
</feComponentTransfer>
</filter>
</defs>
<image x="0" y="0" width="300" height="200" xlink:href="three.jpg" />
<image x="0" y="200" width="300" height="200"
xlink:href="three.jpg" filter="url(#discrete)" />
右上圖是原圖,右下圖是調整顏色後的圖像。
<filter id="paint" filterUnits="userSpaceOnUse"
x="0" y="200" width="300" height="250">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 .5 1 1"/>
<feFuncG type="discrete" tableValues="0 .5 1"/>
<feFuncB type="discrete" tableValues="0"/>
</feComponentTransfer>
</filter>
此選項將區間 [0,1] 中的紅色值映射到以下三個值之一:
(0 到 .25) -> 0; (.25 到 .50) -> .5; (.50 到 .75 和 .75 到 1.0) -> 1。
綠色通道前段、中段和後段,分別映射到 0%、50% 或 100% 綠色。
藍色通道(在此特定圖像中相對微不足道)被抑制為黑色(完全消除其效果)。
原圖像沒有 alpha 通道(每點都是不透明的),因此不需要修改該通道。
<defs>
<filter id="linear" filterUnits="objectBoundingBox"
x="0%" y="0%" width="100%" height="100%">
<feComponentTransfer>
<feFuncR type="linear" slope="1" intercept="0" />
<feFuncG type="linear" slope="0" intercept="0" />
<feFuncB type="linear" slope="1" intercept="0" />
</feComponentTransfer>
</filter>
</defs>
<image x="0" y="0" width="300" height="200" xlink:href="three.jpg" />
<image x="0" y="200" width="300" height="200"
xlink:href="three.jpg" filter="url(#Linear)" />
輸出 = amplitude * pow(輸入,exponent) + offset
<defs>
<filter id="Gamma" filterUnits="objectBoundingBox"
x="0%" y="0%" width="100%" height="100%">
<feComponentTransfer>
<feFuncR type="gamma" amplitude="2" exponent="3" offset="0" />
<feFuncG type="gamma" amplitude="2" exponent="2" offset="0" />
<feFuncB type="gamma" amplitude="2" exponent="1" offset="0" />
</feComponentTransfer>
</filter>
</defs>
<image x="0" y="0" width="300" height="200" xlink:href="three.jpg" />
<image x="0" y="200" width="300" height="200"
xlink:href="three.jpg" filter="url(#Gamma)" />