はじめに
Webサイトのレビュー時に「PNGの方が綺麗なので、SVGから変更して欲しい」という連絡が来ました。
通常SVGなどのベクター画像よりも、PNGなどのラスタ画像が綺麗になる事はありません。
ですが今回通説とは逆の事が発生してしまったようなので、急遽アサインされ原因を調査することになりました。
問題の画像を確認
問題の画像をここに貼ることは諸事情で出来ませんが、曲線が多いベクター画像でした。
詳細な内容を確認したところ、曲線部分にジャギーが発生しているという趣旨の内容でした。
確かにPNGファイルを確認すると、SVG画像よりも曲線が滑らかな気がします。
そこで、SVGのジャギーを減らす方法について模索してみました。
shape-rendering
SVGの表示時には、基本的にアンチエイリアスが掛かるようになっています。
shape-rendering
というCSSプロパティが存在していて、ここの値を変更することによりある程度SVG-UAに指示を出来ますが、ここを変更しても変わりませんでした。
auto
ですが、 geometricPrecision
にしても見た目は変わりませんでした。 アンチエイリアス
SVGレンダリング時にアンチエイリアスの設定を変更出来れば良いのですが、プロパティとして存在しなさそうでした。
そこで同じ現象を検索してみるとChromiumのIssueとして上がっていました。
どうやら本件の問題と似ています。
https://issues.chromium.org/issues/40827297確かにiPhoneなどで確認すると、Chromiumに比べて綺麗に表示されるように見えました。
ただ環境依存で片付けるのも問題があるので、別の作戦を考える必要がありました。
PNG画像が滑らかに見える理由
今度は趣向を変えてSVG画像でジャギーを減らす方法では無く、PNG画像が何故滑らかに見えるのか考えることにしました。
ここで映像処理などに興味があった昔の経験が生きました。
ブラウザは通常ラスタ画像を拡大するときに、Bilinearなどで補間されます。
Bilinearの特長として、スムージング処理が行われてぼやけた印象になります。
このぼやけた印象が返って、アンチエイリアスが掛かったような印象になっていたと気がつきました。
対策
SVGよりもPNGの方が良いというのは、つまりぼやけた表現の方が合っているということです。
つまりSVGにぼかしを若干入れると良いと言うことが分かりました。
具体的にはSVGでBlurフィルターを使ってあげればOKです。
https://developer.mozilla.org/ja/docs/Web/SVG/Tutorial/Filter_effectsさいごに
「ベクター画像はラスタ画像よりも綺麗」という固定概念がありましたが、必ずしも成り立たないという経験が出来ました。
前述した通りラスタ画像は場合によってはぼやけた印象になるので、SVGと一緒に置いた時に違和感が出ることもあります。
その時はSVGを微妙にぼかすことにより、サイトの印象を改善することが出来るかも知れません。一方でiOSやmacOSのSafariなどでは、そのままでもSVGが綺麗に表示されるため、端末やブラウザ依存なところがある点には注意です。