mieki256's diary



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 指定してみても、出力画像のサイズが変わるだけで、一部分しか変換されないのは同じだった。

_単位換算計算スクリプト :

上記ページを使って計算すると、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 の計算結果のほうが合っている。たぶん。

_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を作って変換させてみたが、そのはみ出したパーツ全ては出力されなかった。

オプション無しで出力した画像をフォトレタッチソフトで開いて、切り出す座標値を取得して、それを指定して再度変換してやればいいのですが。手作業・目視確認作業が入ってきてしまうわけで。何故、計算のみでズバッと指定値が求められないのであろうか。トホ。

_国によって長さが違うポイント単位 :

同じ「ポイント」といっても、実は各国によって微妙に長さが違う。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 か?

つまり :

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 の画像が得られた。正解だった。

まとめ :

Batik で Sodipodi のデータを、ページサイズでピッタリのラスター画像に変換したい場合は、
  • 必ず、-dpi 90 をつける。
  • 大きい画像サイズで出力したい場合は、-w 画像の横幅、あるいは、-h 画像の縦幅を指定する。(片方指定すれば、もう片方は勝手に計算してくれる)
という感じかしら。たぶん。

例: java -jar batik-rasterizer.jar -dpi 90 -w 1600 hoge.svg
… 1600 x ? dot の hoge.png を得る。

でもなんとなく :

90 dpi って、ウチの環境特有の値ではないのかという不安も… (;´Д`)

*1: この場合の dpi は、ppi みたいなものなんだろう。たぶん。
*2: 8.4 x 72 = 604.8 。
*3: 210 / 25.4 = 8.26771653… ≒ 8.27 inch 。
*4: 210 mm = (210/25.4) inch 。90dpi だから、(210/25.4) * 90 ≒ 744 dot。

以上です。

過去ログ表示

Prev - 2004/06 - Next
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project