2012年11月29日木曜日

svgの描画品質に影響を与える操作・まとめ

一般にsvgを使ったグラフィック描画は出力デバイスの種類に依らず美しい結果が得られるとされています.ですが本当にそうなのでしょうか?ここではsvgを使ったのに品質の低下を招いてしまうパターンについてまとめて見ることとします.


svgの出力結果が美しい理由


まず,「出力デバイスの種類に依らず美しい結果が得られる」とは具体的にはどのようなことを指しているのでしょうか?

ディスプレイやプリンターを含めた出力デバイスは通常ラスタ画像の出力に特化しています.これらのデバイスには解像度と呼ばれる固有の値が定義されており,この値に従って画像を細かい部分に分割することでグラフィックを表現しています.

一方のsvgはベクタ形式と呼ばれる方法で画像を表現しており,そのままではラスタ画像を扱うデバイスでは表示することができません.従ってコンピュータはベクタ形式からラスタ形式への変換を自動的に行うことでベクタ形式の表示を行なっているのです(これをラスタライズと呼びます). その際,デバイスごとの解像度を考慮し,最適なラスタ画像に変換しているので「出力デバイスを選ばずに美しい」のです.

つまり,この最適なラスタライズを壊す操作を行えば,いかなsvgと言えども美しくない結果が得られてしまうこともあるのです.

最適なラスタライズを壊す操作


ではどのような操作がこの「壊す」 操作に相当するのでしょうか?以下にまとめてみましょう.

1・img要素でsvg画像を読み込んだ場合

意外ですがimg要素でsvg画像を挿入すると,表示される画像はラスタ画像と同等になる場合があります.
img要素でのSVG画像とCSS Transform
これはcss transformに限らず,印刷処理にも影響を及ぼします.従ってsvgを表示させるにはobject要素のほうが適していることになります.

2・transform3dを設定する

インラインsvg要素をしていてもtransform3dを施した場合にグラフィックの滑らかさが失われるケースがあります.
この問題には根本的な解決策が無いと考えられるので,極力使わないほうが良いでしょう.

3・pattern要素を用いる

patterns要素による塗り潰しは事前にラスタライズされるため,svgを印刷した際にラスタ画像として出力されます.
住所ラベルをsvgで作ろう→pattern要素の罠
繰り返しレイアウトを作るのであればpattern要素の代わりにuse要素が使えないか検討してください.

4・svgfilterを掛ける

filterを掛けることで図形には画像処理を掛けるための解像度が設定されます.この値は通常ディスプレイの解像度に依存するため,印刷時にエッジのぼやけなどを生じてしまいます.
処理速度を犠牲にして良いのであれば,filterRes属性の値を大きく取ることで改善できるかも知れません.

5・canvas要素に描画する

canvas要素はラスタ画像であるため,svgグラフィックをcanvas要素に描画することでベクタ画像としてのメリットが喪失します.


これらの中にはディスプレイ表示時はそれほど気にならないものの,印刷時に初めて気がつくものもあり,意外に厄介な問題です.特にsvgを自作する場合,効率的なコーディングをすればするほど後々の方針変更が難しいといった面もあるので,印刷を念頭に入れるのであれば慎重に作業を行ったほうが良いでしょう.

0 件のコメント:

コメントを投稿