パソコン・メモメモ備忘録

気の向くままパソコン関係等で気になることを書き記す。時々更新!

SVG ファイルのスケール

実寸で SVG ファイルを生成したいと思ったのだが、これが結構難しいことがわかった。未だ完全に把握できたわけではないが、少しメモっておく。ツールは、ChromeInkscapeImageMagick の Convert。

まず重要なのは、これらツール(レンダラ)それぞれに固有の単位があるということ。SVG の中の数値で、明示的に単位を書いていないものは、単位がユーザ・ユニットというもので、デフォルトでは、Chrome (Web ブラウザ系?)は 1/96 インチ、Inkscape と Convert は 1/90 インチ(ImageMagick は 1/72 という情報もあり)。ちなみに Illustrator は 1/72 インチ(1 ポイント(pt))だそうな。ということで、ChromeInkscape で微妙に表示が違うことがあるのは、この差が出ている可能性がある。

実寸で出したい場合は、svg タグの width と height アトリビュートは、実寸(単位付き)で指定して、ViewBox もそれと同じ数値にしておくと、ユーザ・ユニットがその単位になるようだ。実寸に拘る場合は深く考えずにそうしておくのが吉っぽい。

ただし、ここで大きいトラップがあって、それに引っかかってしまった。例えば、ユーザ・ユニットを inch にした場合、SVG ファイル内で、単位付きの数値を使った場合、それはその単位通りの大きさ(長さ)にはならない。上記に書いた、デフォルトのユーザ・ユニットを inch に換算しているその係数が掛かるのだ。Chrome でユーザ・ユニットを inch にすると 72 倍されているわけなので、1mm が 72mm になったりする。なので、SVG ファイル内で、実寸とする単位は一つにしておいた方が混乱を招かなくていい、というかそうすべきだ。

とりあえずこれで、思ったような出力を得ることができた。

もう一つ引っかかったのは、ImageMagick の Convert で ビットマップ系フォーマットに変換する際の -density の指定。どういう仕様なのか良く解らないが、SVG ファイル内の ユーザ・ユニットに影響するのと同時に、出力するビットマップの dpi が指定されて、デフォルトの 1/90 インチとの比が2乗された形の出力が得られてしまう。これは正しい仕様なのか? 対策としては、実際の解像度の 90(dpi) との比の平方根を 90 に掛けた density を指定して、svg ファイルを読み込んで、出力画像を指定する手前で、もう一度 density で出力したい dpi を設定すると所望の結果が得られる。
convert -density (90*sqrt(X/90)) INPUT.svg -density X OUTPUT.png
みたいな感じ。

ただ、density は整数値しか受け付けないみたいなので、dpi の計算誤差が気になる。一度大きめの dpi にして -geometry を使って所望のピクセル数の画像を得るのがいいかもしれない。

なんだかなぁ。