SVG/フィルタ

フィルタ演算  filter 要素

属性
id フィルタ名
グラフィックフィルタを定義します。
filter要素の中に原始フィルタ(またはフィルタ・プリミティブ)と呼ばれるフィルタ演算を1つ以上設定します。
<filter id="フィルタ名">
    <原始フィルタ... />
    <原始フィルタ... />
</filter>
フィルタをグラフィックに適用するときのfilter属性には、id属性に定義したフィルタ名を指定します。
filter="url(#フィルタ名)"

輪郭をぼかす  feGaussianBlur 要素

属性
stdDeviation ぼかしの幅
"x y"のように、縦横方向で異なるぼかし幅を指定できる。
ガウシアン・ブラー演算によりグラフィックの輪郭をぼかします。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Blur">
        <feGaussianBlur stdDeviation="1"/>
    </filter>

    <circle cx="50" cy="50" r="20"
        fill="green" filter="url(#Blur)"/>
</svg>
Picture

位置の移動  feOffset 要素

属性
dx X方向の移動量
dy Y方向の移動量
元のグラフィックに対し表示位置を移動してずらします。
feOffsetを使う場合は、filter要素に、
filterUnits="userSpaceOnUse"
を指定しなければなりません。元のグラフィックの描画領域からはみ出す結果を出力しないためです。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Offset" filterUnits="userSpaceOnUse">
        <feOffset dx="-5" dy="10"/>
    </filter>
    <circle cx="50" cy="50" r="20"
        stroke-width="1" stroke="purple" fill="none"/>
    <circle cx="50" cy="50" r="20"
        stroke-width="1" stroke="red" fill="none" filter="url(#Offset)"/>
</svg>
Picture

色の変換  feColorMatrix 要素

属性
type 演算の種類
matrix:RGBAを変換する5行×4列の行列
saturate:彩度
hueRotate:色相回転
values 演算の設定値
matrixは、次の行列の各値に0〜1の範囲の係数を指定する。values = "
a00 a01 a02 a03 a04
a10 a11 a12 a13 a14
a20 a21 a22 a23 a24
a30 a31 a32 a33 a34"
元のグラフィックのピクセルが「R、G、B、A」の各値(0〜100%)であるとき、変換により出力する各色「R'、G'、B'、A'」は次の式で導かれる。
R' = a00*R + a01*G + a02*B + a03*A + a04
G' = a10*R + a11*G + a12*B + a13*A + a14
B' = a20*R + a21*G + a22*B + a23*A + a24
A' = a30*R + a31*G + a32*B + a33*A + a34
「R'、G'、B'、A'」は0〜1の範囲とする(1以上は1に切り捨てられる)。
saturateは0~1(0 はモノクロ)、hueRotateは回転角の0~360で指定。
行列演算によりRGBAの色を変換します。
行列の与え方によりあらゆる色の変換が可能になりますが、彩度と色相は saturate属性とhueRotate属性へパラメータを与えるだけに簡略化されており、行列を作ることなく調整できます。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Matrix">
        <feColorMatrix type="matrix"
            values="0 0 0 0 0
                    0 0 0 0 0
                    1 1 1 1 0
                    0 0 0 1 0"
/>
    </filter>
    <filter id="Saturate">
        <feColorMatrix type="saturate" values="0.2"/>
    </filter>
    <filter id="HueRotate">
        <feColorMatrix type="hueRotate" values="180"/>
    </filter>
    <circle cx="50" cy="30" r="15"
        stroke-width="3" stroke="blue" fill="orange"/>
    <circle cx="20" cy="70" r="15"
        stroke-width="3" stroke="blue" fill="orange" filter="url(#Matrix)"/>
    <circle cx="50" cy="70" r="15"
        stroke-width="3" stroke="blue" fill="orange" filter="url(#Saturate)"/>
    <circle cx="80" cy="70" r="15"
        stroke-width="3" stroke="blue" fill="orange" filter="url(#HueRotate)"/>
</svg>
Picture
上のmatrixの変換は、元のピクセルのRGBと透明度AをすべてB(青)に置き換えます。3行目がすべて1なので、元がどのような色(例えば限りなく黒に近いグレー)でも完全な青に置き換えられます。この例で完全な青にならない元画像の色とは、完全に透明な黒のみです。
全く元と同じ出力となるmatrixの行列は次のようになります。
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
また、行列の5列目はRGBAのいずれにも該当しませんが、変換後の色に一律の係数を与えます。例えば次のようにすると、全般が少し青がかった色になります。
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0.1
0 0 0 1 0

画像入力  feImage 要素

属性
xlink:href 画像ファイル
名前空間「xmlns:xlink="http://www.w3.org/1999/xlink"」の宣言が必要。
x y 画像の座標
width height 画像の幅・高さ
画像ファイル(JPEG、PNG、SVG)をフィルタの入力に取り込みます。
描画範囲の周囲10%を足した範囲の画像が切り抜かれます。下の例の黄色い矩形は実際の範囲を示しています。画像が少し大きめに切り抜かれていることがわかります。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <filter id="Image">
        <feImage xlink:href="imagecountach.jpg"
            x="0" y="0" width="100" height="100"/>

    </filter>
    <rect x="20" y="20" width="60" height="60"
        fill="none" filter="url(#Image)"/>
    <rect x="20" y="20" width="60" height="60"
        stroke-width="2" stroke="yellow" fill="none"/>
</svg>
Picture

画像をタイル状に配置  feTile 要素

属性
x y 画像の座標
width height 画像の幅・高さ
入力画像をタイル状に並べて出力します。
通常はfeImageの画像をfeTileの入力として組み合わせます。また、タイルの1つの周囲は実際より10%が大きく切り抜かれます。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <filter id="Tile">
        <feImage xlink:href="imagecountach.jpg"
            x="0" y="0" width="50" height="50"/>

        <feTile  x="0" y="0" width="100" height="100"/>
    </filter>
    <rect x="20" y="20" width="60" height="60" fill="none" filter="url(#Tile)"/>
</svg>
Picture

単色の塗りつぶし  feFlood 要素

属性
flood-color 塗りつぶす色
flood-opacity 塗りつぶす色の不透明度
x y 画像の座標
width height 画像の幅・高さ
単色で塗りつぶした画像を出力します。
描画範囲の周囲10%を足した範囲が切り抜かれます。下の例の黄色い矩形は実際の範囲を示しています。少し大きめに切り抜かれていることがわかります。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Flood">
        <feFlood flood-color="navy" flood-opacity="0.3"
            x="0" y="0" width="100" height="100"/>

    </filter>
    <rect x="20" y="20" width="60" height="60"
        stroke="yellow" stroke-width="1" fill="none"/>
    <rect x="20" y="20" width="60" height="60" filter="url(#Flood)"/>
</svg>
Picture

色を変換  feComponentTransfer 要素

属性
type 変換関数
linear:線形
gamma:ガンマ補正
slope 一次関数傾き(linear)
intercept 一次関数切片(linear)
amplitude ガンマ増幅率(gamma)
exponent ガンマ補正指数(gamma)
offset オフセット(gamma)
RGBAへの変換関数により、色調補正など色を変換します。
feComponentTransfer要素の中で、RGBA のそれぞれに対応した関数を指定する次の要素
feFuncR、feFuncG、feFuncB、feFuncA
によって、関数の種類とパラメータを与え色を変換します。
実際には feFuncR,G,B,A要素で属性を設定し、feComponentTransfer要素はそれらの定義をまとめるだけに使います。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <filter id="ComponentTransfer">
        <feImage xlink:href="imagekyoto.jpg"
            x="50" y="50" width="50" height="50"/>
    <feComponentTransfer>
        <feFuncR type="linear" slope="-1" intercept="1"/>
        <feFuncG type="linear" slope="-1" intercept="1"/>
        <feFuncB type="linear" slope="-1" intercept="1"/>

    </feComponentTransfer>
    </filter>
    <image xlink:href="imagekyoto.jpg"
        x="0" y="0" width="50" height="50"/>
    <rect x="50" y="50" width="50" height="50" filter="url(#ComponentTransfer)"/>
</svg>
Picture

テクスチャー模様生成  feTurbulence 要素

属性
type 関数の種類
fractalNoise:ノイズ関数
turbulence:ゆらぎ関数
baseFrequency 関数の周波数(0~1 未満)
seed 乱数のシード(デフォルトは 0)
numOctaves テクスチャーの細かさ(1~)
パーリンノイズと呼ばれるアルゴリズムにより大理石のようなテクスチャー模様を生成します。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Turbulence">
        <feTurbulence type="turbulence"
            baseFrequency="0.05" numOctaves="2" seed="1"/>

    </filter>
    <rect x="20" y="20" width="60" height="60" filter="url(#Turbulence)"/>
</svg>
Picture

複数の原始フィルタの接続

原始フィルタは、filter要素の中で複数指定が可能で、上の演算結果をその下のフィルタの入力になるよう演算結果を順次接続しながら適用し、最終的な結果がグラフィックに反映します。そのようにして原始フィルタを組み合わせていろいろな映像効果を作ることができます。
次の例では、ガウシアン・ブラーで輪郭をぼかし、色変換で彩度を落とすという2段界のフィルタを通過させています。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="BlurSaturate">
        <feGaussianBlur stdDeviation="2"/>
        <feColorMatrix type="saturate" values="0.4"/>

    </filter>
    <circle cx="50" cy="50" r="20"
        stroke-width="1" fill="green" filter="url(#BlurSaturate)"/>
</svg>
Picture
各原始フィルタの要素には、inresultという属性があり、これらにフィルタの入力と結果の名前をつけることで、明示的なフィルタ間の入出力の操作ができます。これらは特にフィルタの併合(feMerge)、合成(feComposite、feBlend)で効果を発揮します。inresultを省略した場合は、上のresultが下のinに渡されます。

フィルタ出力を併合  feMerge 要素

属性
in 重ね合わせるフィルタの結果result、またはSourceGraphic
フィルタの結果を重ね合わせ併合してきます。
feMerge要素の中に複数のfeMergeNode要素並べ、それぞれのin属性に指定するフィルタの出力結果(原始フィルタのresult属性には出力結果の名前を指定できる)、あるいはSourceGraphic(元のグラフィック)を指定し、feMergeNode要素への入力を順に重ね合わせた結果を出力します。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Merge">
        <feOffset dx="3" dy="3" result="offsetout"/>
        <feMerge>
            <feMergeNode in="offsetout"/>
            <feMergeNode in="SourceGraphic"/>
        </feMerge>

    </filter>
    <circle cx="50" cy="50" r="20"
        stroke-width="1" stroke="blue" fill="gold" filter="url(#Merge)"/>
</svg>
Picture

透明度を入力するドロップシャドウ

原始フィルタのinSourceAlphaを指定すると、元画像の透明度のみを入力することができます。これをfeMerge・feMergeNode要素と合わせると、図形の影「ドロップシャドウ」を作ることができます。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Shadow" filterUnits="userSpaceOnUse">
        <feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blurout"/>
        <feOffset in="blurout" dx="2" dy="2" result="offsetblurout"/>
    <feMerge>
        <feMergeNode in="offsetblurout"/>
        <feMergeNode in="SourceGraphic"/>
    </feMerge>
    </filter>
    <circle cx="50" cy="50" r="20"
        stroke-width="1" stroke="blue" fill="gold" filter="url(#Shadow)"/>
</svg>
Picture

フィルタ出力を合成  feComposite 要素

属性
in 合成するフィルタの結果
in2 合成するもう一つのフィルタの結果
operator 演算方法
over in2の上にinを重ねる。
in 両方の共通部分を抜き出す。
out in2の部分だけ抜き出す。
atop in2の上にinを重ね、in2の領域だけ抜き出す。
xor 両方の共通部分を除いて抜き出す。
arithmetic k1 k2 k3 k4属性の値により、全画素に対し次の計算結果を出力する。
k1・in・in2 + k2・in + k2・in2 + 4
例えばinが70%でin2を30%の割合で混合する場合は、
k1="0" k2="0.7" k3="0.3" k4="0"
のようにk2 k4に割合を設定する。
k1 k2 k3 k4 arithmetic演算パラメータ
2つのフィルタの結果を合成します。
feComposite要素のin属性とin2属性に、2つのフィルタの出力結果を入力し、operator属性で指定する各種演算により合成します。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Xor" filterUnits="userSpaceOnUse">
        <feOffset dx="20" result="ofsout"/>
        <feComposite operator="xor" in="SourceGraphic" in2="ofsout"/>
    </filter>

    <filter id="Arithmetic" filterUnits="userSpaceOnUse">
        <feOffset dx="20" result="ofsout"/>
        <feComposite operator="arithmetic" in="SourceGraphic" in2="ofsout"
            k1="0" k2="0.7" k3="0.3" k4="0"/>
    </filter>

    <circle cx="40" cy="30" r="15"
        stroke-width="2" stroke="blue" fill="red" filter="url(#Xor)"/>
    <circle cx="40" cy="70" r="15"
        stroke-width="2" stroke="salmon" fill="green" filter="url(#Arithmetic)"/>
</svg>
Picture

照明効果・拡散反射  feDiffuseLighting 要素

属性
lighting-color 光源の色
surfaceScale 完全に不透明な面の高さ(大きいほど高さのある立体として計算される)
diffuseConstant 照明の拡散定数(大きいと光が強くなる)
光源から照明を当てた場合の拡散反射の結果を取得します。
ハイライトとして反射している箇所ほど不透明になるような光源の色で描かれたグラフィックを出力します。
照明効果の要素と共に、以下のような光源の要素と属性を指定し、光の当たり方を設定します。
光源要素・属性
feSpotLight スポットライト(光の当たる範囲がある)
pointsAtZ pointsAtY pointsAtZ スポットが当たる座標
limitingConeAngle 角度
specularExponent 範囲(1 以下で小さいほど狭い)
fePointLight 点光源(ある一転から放射状に光が当たる)
x y z 光源の座標
feDistantLight 平行光源(無限遠から平行に光が当たる)
azimuth 水平方向角
elevation 垂直方向角
次の例は、円に対し各設定の状況に従い光を当てたときの、光が強く当たっている場所がより不透明になるような情報のみを表しています。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="DiffuseLight" filterUnits="userSpaceOnUse">
        <feDiffuseLighting
            surfaceScale="5"
            lighting-color="yellow"
            diffuseConstant="1"
            result="diffpointout">
            <fePointLight x="10" y="10" z="40"/>

        </feDiffuseLighting>
    </filter>
    <circle cx="50" cy="50" r="30" filter="url(#DiffuseLight)"/>
</svg>
Picture
feDiffuseLightingフィルタからの出力だけでは、光の拡散反射の情報しか得られません。フィルタから出力された光の反射画像と元のグラフィックを合成することで、次のように、赤い円に斜め上から黄色い光を当てたときの最終的な見え方が得られます。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="DiffuseLight" filterUnits="userSpaceOnUse">
        <feDiffuseLighting
            surfaceScale="5"
            lighting-color="yellow"
            diffuseConstant="1"
            result="diffpointout">
            <fePointLight x="10" y="10" z="40"/>
        </feDiffuseLighting>
        <feComposite operator="in"
            in="diffpointout" in2="SourceAlpha" result="comp1"/>
        <feComposite operator="arithmetic"
            in="SourceGraphic" in2="comp1"
            k1="0" k2="1" k3="1" k4="0"/>
    </filter>
    <circle cx="50" cy="50" r="30" fill="red" filter="url(#DiffuseLight)"/>
</svg>
Picture

照明効果・鏡面反射  feSpecularLighting 要素

属性
lighting-color 光源の色
surfaceScale 完全に不透明な面の高さ(大きいほど高さのある立体として計算される)
specularConstant 照明の拡散定数(大きいと光が強くなる)
specularExponent 鏡面指数 1~128(鏡度合いの強さ)
光源から照明を当てた場合の鏡面反射の結果を取得します。
ハイライトとして反射している箇所ほど不透明になるような光源の色で描かれたグラフィックを出力します。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Specular" filterUnits="userSpaceOnUse">
        <feSpecularLighting
            surfaceScale="20" lighting-color="yellow"
            specularConstant="1" specularExponent="10">
            <fePointLight x="40" y="40" z="30"/>
        </feSpecularLighting>

    </filter>
    <circle cx="50" cy="50" r="30" filter="url(#Specular)"/>
</svg>
Picture
feSpecularLightingフィルタからの出力だけでは、光の鏡面反射の情報しか得られません。フィルタから出力された光の反射画像と元のグラフィックを合成することで、最終的な見え方が得られます。
<svg width="10cm" height="10cm" viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg">
    <filter id="Specular" filterUnits="userSpaceOnUse">
        <feSpecularLighting
            surfaceScale="20"
            lighting-color="yellow"
            specularConstant="1"
            specularExponent="10"
            result="specupointout">
            <fePointLight x="40" y="40" z="30"/>
        </feSpecularLighting>
        <feComposite operator="in"
            in="specupointout" in2="SourceAlpha" result="comp1"/>
        <feComposite operator="arithmetic"
            in="SourceGraphic" in2="comp1"
            k1="0" k2="1" k3="1" k4="0"/>
    </filter>
    <circle cx="50" cy="50" r="30" fill="red"
        filter="url(#Specular)"/>
</svg>
Picture