今回は「SVGファイルの変換」について。拡大しても滑らかさを保てるベクター画像フォーマットのSVGは、インターネット上に高品質なクリップアートが多数公開され、文書の挿し絵などに重宝する。しかし対応するソフトは多いとはいえず、現状ではフォーマット変換が必要になる。それをスマートに解決しよう、というのが今回の趣旨だ。
いまなお扱いにくい「SVG」
XMLで2Dベクター画像を表現する仕様の「SVG」。以前からイラストソフトを中心に利用されてきたが、HTML5で文書に直接SVGの要素を記述(インラインSVG)できるようになったことをきっかけに、再び注目が集まっている。SafariやChrome、Firefoxなど多くのWebブラウザにサポートされ、JavaScriptを利用したインタラクティブなコンテンツを見かける機会も急増した感がある。
しかし、拡張子「.svg」のファイルとして見た場合、扱いにくさは相変わらずだ。OS Xに標準装備の「プレビュー」では開くことができず、Adobe IllustratorやInkScapeといったイラストソフトか、SafariなどのSVGをサポートするWebブラウザを使うしかない。
手軽なのはWebブラウザだが、フォーマット変換は難しい。SVGを他のフォーマットに変換(ラスタライズ)したいというニーズはあるはずで、そうなるとSVGをサポートするソフトに頼らざるをえない。
「qlmanage」を使う
だが、SVGファイルをFinderで見ればわかるとおり、サムネイルはしっかりと表示される。これはシステムレベルでSVGがサポートされていることの証明で、QuickLookでプレビューすることもできる。標準装備のQuickLookプラグイン「Web.qlgenerator」が、SVGのプレビューとサムネイル作成を担う実行部分だ。
このQuickLookプラグインは、「qlmanage」コマンドを利用すると画像フォーマット変換ツール代わりに使える。qlmanageコマンドには、フォーマットを変換する機能/オプションは用意されていないものの、任意のサイズでサムネイルを作成するオプションがあるので、巨大なサムネイルを作成しそれを変換後の画像ファイルとみなす、というわけだ。
使い方はかんたん、サムネイルを作成するための「-t」オプションと、サムネイルのピクセル数を決めるための「-s」オプション、サムネイル(PNG画像)の生成場所を決めるための「-o」オプション(出力先としてカレントディレクトリを表す「.」を指定する)、最後にSVGファイルを引数として与えればOK。以下の要領でコマンドを実行すると、カレントディレクトリに一辺が800ピクセルの「Tiger.svg.png」が作成されるはずだ。
$ qlmanage -t -s 800 -o . Tiger.svg
「PhantomJS」を使う
SVGをPNGに変換することだけが目的であれば、qlmanageコマンドで用は足りる。しかし、背景の透過情報は無視され白へと一律に変換されてしまうため、サムネイルとして使うならともかく、他の用途で使うには不満が残る。一辺のサイズしか指定できないため、必ず正方形になってしまう点も困りものだ。
そこで注目したのが「PhantomJS」。WebKitをヘッドレス(対話的UIを取り除く持たない)化しJavaScriptのAPIを利用できるようにしたツールで、コマンドラインからWebページのスクリーンショットを撮るなど、ユニークな処理ができる。Safari/WebKitがサポートする機能にひととおりアクセス可能なため、CanvasやSVGの描画結果を画像化する用途にも活用できるのだ。
PhantomJSのインストール
(ダウンロードしたZIPファイルをデスクトップに置いた状態から操作)
$ cd ~/Desktop
$ unzip phantomjs-1.9.1-macosx.zip
$ cd phantomjs-1.9.1-macosx
$ sudo cp bin/phantomjs /usr/local/bin/
スクリーンショットや描画ができるといっても、作業の指示はJavaScript経由で行うため、ある程度のコーディング知識は必要だ。しかし、PhantomJSには多数のサンプルが用意されており、そのうち「rasterize.js」というコードを利用すれば、SVGをPNGに変換することができる。
たとえば、PhantomJSのパッケージを展開したディレクトリに対象のSVGがあるとき、以下のとおりコマンドを実行すれば、600×600ピクセルのPNG画像がカレントディレクトリに生成される。
$ phantomjs examples/rasterize.js Tiger.svg out.png
ただし、この「rasterize.js」はviewportサイズが600×600で決め打ちされているため、任意のサイズの画像を生成できない。その場合、こちらのスクリプトを利用し、以下の要領で縦横のピクセル数を指定してみよう。これで、横長のSVGも横長のままPNGに変換できるはずだ。
$ phantomjs myscript.js Harley.svg out.png 737 400