2004/06/23(水) [n年前の日記]
#2 [svg] SVG→PNG変換
mapbbs用のアイコン画像を、Sodipodiで描いてたのですが。svgからpngに変換するのが面倒臭い。コマンドラインでサクサク変換できないだろうか。
◎ _Batik - SVG Rasterizer :
Batik という、Javaで書かれたツールを使えば、目的を果たせるらしい。試用してみた。java -jar batik-rasterizer.jar *.svg と打ったら、サラサラと SVG → png 変換された。素晴らしい。と思ったのだけど、なんだかページ外の余分な部分まで出力されてる。うーん。
◎ ImageMagick 6.0.1-Q16 もSVGに対応してるのか :
convert hoge.svg hoge.png と打って変換してみた。ダメ。エラーメッセージが出る。とはいえ、結果画像は得られた。しかし、グラデーションが真っ黒に。完全に対応できてるわけではないらしい。残念。どうやら Batik で作業するしかないらしい。
◎ 試行錯誤 :
batik-rasterizer.jar に -a x,y,w,h オプションを渡して、「ここからここまでを出力せよ」と指定すればいいのだろうか。でも、そこで指定する浮動小数点とやらの単位は何だろう。pixelsか、mmか、inchか。
-w width、-h heightというオプションもあるけれど。それらは、最終的な画像サイズを指定するものらしい。その指定サイズの中に、ページ全体が収まるように拡大縮小されて変換される。特定の領域のみラスター画像にしたいという目的からは外れてしまう。
-a オプションを指定してみたけど、やはり単位がわからない。元となるSVGは、ページサイズを 210mm x 210mm にしている。SVGファイルをテキストエディタで覗いたら、width、height が 595.2756 point と書かれていた。Batik での変換時に、-a 0,0,595.2756,595.2756 と指定。一部分しか変換されない。つまり、単位は point ではないのだな。-dpi 72 or 96 を *1 指定してみても、出力画像のサイズが変わるだけで、一部分しか変換されないのは同じだった。
-w width、-h heightというオプションもあるけれど。それらは、最終的な画像サイズを指定するものらしい。その指定サイズの中に、ページ全体が収まるように拡大縮小されて変換される。特定の領域のみラスター画像にしたいという目的からは外れてしまう。
-a オプションを指定してみたけど、やはり単位がわからない。元となるSVGは、ページサイズを 210mm x 210mm にしている。SVGファイルをテキストエディタで覗いたら、width、height が 595.2756 point と書かれていた。Batik での変換時に、-a 0,0,595.2756,595.2756 と指定。一部分しか変換されない。つまり、単位は point ではないのだな。-dpi 72 or 96 を *1 指定してみても、出力画像のサイズが変わるだけで、一部分しか変換されないのは同じだった。
◎ _単位換算計算スクリプト :
上記ページを使って計算すると、210 mm = 8.4 inch になる。72dpi、8.4 inch なら 604.8 dot になるはず。
*2
-a に指定してみた。…ダメ。一部分しか出てこない。
◎ Sodipodiの単位換算 :
実験に使ってるSVGのページサイズは、210mm x 210mm 。Sodipodiの、ファイル → 出力 を選んで、単位を色々選んでみた。cm や、m は、10や100で割るだけだから間違いようがない。しかし、inch にしたら、8.27 と出た。前述ページの結果と違う。何故。…前述ページで、mm → inch → mm を繰り返すと、どんどん値がずれていく。どうやらかなり大雑把な計算をしてるらしい。Sodipodi のほうが正確かも。
◎ 1 inch = ? mm :
_国際単位比較チャート
_単位換算 長さの換算
1 inch = 25.4 mm (1 inch = 0.0254 m) らしい。ということは、210mm ≒ 8.27 inch となる。 *3 やはり、Sodipodi の計算結果のほうが合っている。たぶん。
_単位換算 長さの換算
1 inch = 25.4 mm (1 inch = 0.0254 m) らしい。ということは、210mm ≒ 8.27 inch となる。 *3 やはり、Sodipodi の計算結果のほうが合っている。たぶん。
◎ _Pixel換算 :
_(via Fortunefield)
そのものズバリの換算スクリプトがあった。ありがたい。
計算してみた。 _Batik - SVG Rasterizer のページによると、デフォルトは 96 dpi。前述ページで、96 dpi、210 mm と打ち込むと、793.7007874015749 pixel になる。 batik-rasterizer.jar で、210mm x 210mm のSVGを、オプション無しで変換すると、793x793の画像が出力される。Pixel換算の結果と、バッチリ一致する。
ところが、その793x793の中には、ページ外にはみ出したパーツまで描画されてるわけで。…アレかな。Batik は、ページサイズに対応した画像サイズを、一度はしっかり求めておきながら、その後、その画像サイズにあらゆるパーツが収まるように、わざわざ画像を縮小して変換してるということか。…と思ったがそうでもないらしい。ページ外に、かなり盛大にパーツがはみ出してるSVGを作って変換させてみたが、そのはみ出したパーツ全ては出力されなかった。
オプション無しで出力した画像をフォトレタッチソフトで開いて、切り出す座標値を取得して、それを指定して再度変換してやればいいのですが。手作業・目視確認作業が入ってきてしまうわけで。何故、計算のみでズバッと指定値が求められないのであろうか。トホ。
そのものズバリの換算スクリプトがあった。ありがたい。
計算してみた。 _Batik - SVG Rasterizer のページによると、デフォルトは 96 dpi。前述ページで、96 dpi、210 mm と打ち込むと、793.7007874015749 pixel になる。 batik-rasterizer.jar で、210mm x 210mm のSVGを、オプション無しで変換すると、793x793の画像が出力される。Pixel換算の結果と、バッチリ一致する。
ところが、その793x793の中には、ページ外にはみ出したパーツまで描画されてるわけで。…アレかな。Batik は、ページサイズに対応した画像サイズを、一度はしっかり求めておきながら、その後、その画像サイズにあらゆるパーツが収まるように、わざわざ画像を縮小して変換してるということか。…と思ったがそうでもないらしい。ページ外に、かなり盛大にパーツがはみ出してるSVGを作って変換させてみたが、そのはみ出したパーツ全ては出力されなかった。
オプション無しで出力した画像をフォトレタッチソフトで開いて、切り出す座標値を取得して、それを指定して再度変換してやればいいのですが。手作業・目視確認作業が入ってきてしまうわけで。何故、計算のみでズバッと指定値が求められないのであろうか。トホ。
◎ _国によって長さが違うポイント単位 :
同じ「ポイント」といっても、実は各国によって微妙に長さが違う。JISポイントはアメリカン・ポイントに準じているが、ミリ換算の方式が日米で異なるので、ミリ表示では違った値になるが、実用上はまったく同じ長さとして扱われているようだ。ナヌー。いや、それでも計算結果は合わないけど>Batikでの変換。
◎ Sodipodiのページ表示範囲に沿うように四角を置いてみた :
SVGファイルの中をテキストエディタで覗くと、744.094482 x 744.094482 と書いてある。210mm x 210mm、96dpiなら、793 pixel になるはずだが。うーん。
線幅2mmの線を引いてみた。SVG中では、7.0866 と書いてある。 _SVGの単位指定 によると、この数字はピクセル単位らしい。2 mm = (2 * (1/25.4)) inch 。それが、7.0866 pixel になるためには…。7.0866 * 25.4 / 2 = 89.99982 ppi ≒ 90 dpi か?
線幅2mmの線を引いてみた。SVG中では、7.0866 と書いてある。 _SVGの単位指定 によると、この数字はピクセル単位らしい。2 mm = (2 * (1/25.4)) inch 。それが、7.0866 pixel になるためには…。7.0866 * 25.4 / 2 = 89.99982 ppi ≒ 90 dpi か?
◎ つまり :
Sodipodi は、90dpi で各値を求めてるらしい。となると、例えば 210mm x 210mm のページサイズなら、
*4
744x744 dot のサイズになる。…なるほど。だから、793x793 dot の画像が出力されたけど、余分なところまでその中に入ってしまったのか。ということは、-a 0,0,744,744 を指定すれば…。
キター。ピシッと収まった。
ということで、Sodipodi で描いたデータを、Batik でラスターデータに変換するときは、90 dpi で計算して何dotになるか求めた上で、それを -a 0,0,w,h で指定してやればいいと。やっと判った。なるほど。
ちょっと待て。だったら、-dpi 90 を指定するだけでもいいんじゃないか。試してみた。…ピシッと収まりました(爆) -dpi 72 を指定するとどうなるだろう。…画像が切れてますな。つまり、-dpi 90 を指定するだけでいいわけで。ここまでの苦労は一体… orz
いやいや、ちょっと待て。大きなサイズでラスター画像を得たい場合はどうすればいいのか。…もしかして、そういう時に、-w や -h を使うのか。試しに、-dpi 90 -w 1600 と指定してみた。ピシッと収まった 1600 x 1600 の画像が得られた。正解だった。
キター。ピシッと収まった。
ということで、Sodipodi で描いたデータを、Batik でラスターデータに変換するときは、90 dpi で計算して何dotになるか求めた上で、それを -a 0,0,w,h で指定してやればいいと。やっと判った。なるほど。
ちょっと待て。だったら、-dpi 90 を指定するだけでもいいんじゃないか。試してみた。…ピシッと収まりました(爆) -dpi 72 を指定するとどうなるだろう。…画像が切れてますな。つまり、-dpi 90 を指定するだけでいいわけで。ここまでの苦労は一体… orz
いやいや、ちょっと待て。大きなサイズでラスター画像を得たい場合はどうすればいいのか。…もしかして、そういう時に、-w や -h を使うのか。試しに、-dpi 90 -w 1600 と指定してみた。ピシッと収まった 1600 x 1600 の画像が得られた。正解だった。
◎ まとめ :
Batik で Sodipodi のデータを、ページサイズでピッタリのラスター画像に変換したい場合は、
例: java -jar batik-rasterizer.jar -dpi 90 -w 1600 hoge.svg
… 1600 x ? dot の hoge.png を得る。
- 必ず、-dpi 90 をつける。
- 大きい画像サイズで出力したい場合は、-w 画像の横幅、あるいは、-h 画像の縦幅を指定する。(片方指定すれば、もう片方は勝手に計算してくれる)
例: java -jar batik-rasterizer.jar -dpi 90 -w 1600 hoge.svg
… 1600 x ? dot の hoge.png を得る。
◎ でもなんとなく :
90 dpi って、ウチの環境特有の値ではないのかという不安も… (;´Д`)
[ ツッコむ ]
以上です。