Apache batikによるSVG→PNG/JPEGへの変換方法
動作確認OSは、Solaris 9である。
概要
- 公式サイト
- 日本語版ドキュメント
BatikはJava技術に基づく、SVGフォーマットのイメージを、表示する、生成する、変換する、あるいは操作するといった様々な目的で利用する、アプリケーションのためのツールキットである。
ここでは、SVGファイルからPNG/JPEGファイルへのラスタライズのためのコマンドの使用方法、及び、JavaプログラムからのImage Transcoderの呼び出し方法について説明する。
インストールと問題点
インストール
アーカイブを展開して配備するだけ。ただし、Batikのzipファイルを解凍するのにunzipユーティリティを使用しないこと。これはディレクトリのアクセス権限を適切に設定しない。/home/apache/tools/[任意のディレクトリ] バイナリ版 $ jar xvf batik-1.7beta1.zip $ mv batik-1.7 batik-1.7lib (ソース版と区別するために、ディレクトリ名をbatik-1.7libに変更) ソース版 $ jar xvf batik-src-1.7beta1.zip
ターミナルの問題
プログラムの実行はSolarisのコンソール、または、「Reflection X」のコンソール上から行う必要がある。例えば「Tera Term Pro」を使用すると、実行時に下記エラーが出る。"Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ': 0.0' as the value of the DISPLAY variable."
解決方法(2007/09/28追記)
javaプログラム実行時に下記のオプションを指定すること。これは、batikがGraphics2D(2Dグラフィックス用の標準Java API)にイメージの生成を要求しており、Graphics2DがX11サーバーを必要とすることに起因している。JDK 1.4以降では、java.awt.headlessプロパティにtrueをセットすることで、いわゆるheadless(画面を出さない)で実行できるようになる。
java -Djava.awt.headless=true
SVGファイルのヘッダー記述
SVGファイルのヘッダー記述は次の通り。ヘッダー部を追加するのは構わないが、記述不足だと変換できないことがあるので注意すること。<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
使用方法
ラスタライズ(SVG→PNG/JPEG)のコマンド
バイナリ版とソース版で方法が異なる。- Batik - SVG Rasterizerドキュメント
- バイナリ版の例題の実行
apacheユーザーの場合
$ cd /home/apache/tools/batik-1.7lib $ java -Djava.awt.headless=true -jar batik-rasterizer.jar samples/GVT.svg ↓ samples/GVT.png
他のユーザーのディレクトリ上で行う場合
/home/apache/tools/batik-1.7lib/samples/testsディレクトリ以下のファイルが必要なので、自分のディレクトリにコピーしておく
$ cp -r /home/apache/tools/batik-1.7lib/samples/tests . $ java -Djava.awt.headless=true -jar /home/apache/tools/batik-1.7lib/batik-rasterizer.jar svgファイル ↓ PNG/JPEGファイル
java.lang.OutOfMemoryErrorが出るときは、Javaプログラム起動時のオプションで
メモリサイズを指定すること。
$ java -Djava.awt.headless=true -Xmn512m -Xmx1024m -Xms1024m -jar /home/apache/tools/batik-1.7lib/batik-rasterizer.jar svgファイル
apacheユーザーの場合
$ cd /home/apache/tools/batik-1.7 $ chmod +x build.sh $ build.sh svgrasterizer samples/GVT.svg ↓ samples/GVT.png
JavaプログラムからのImage Transcoderの呼び出し
下記サイトにチュートリアルが載っているが、そのままの方法ではうまくいかない。例題のソースを実行してもエラーが出るので、ソースの一部を変更した。イメージのサイズを変更する方法などについては、ドキュメントを参照のこと。- Image Transcoder Tutorialドキュメント
.profileの場合 CLASSPATH=.:〜 :/home/apache/tools/batik-1.7lib/batik.jar .cshrcの場合 setenv CLASSPATH .:〜 :/home/apache/tools/batik-1.7lib/batik.jar
batik-1.7ディレクトリ下でbuild.sh compileを実行し、ライブラリをコンパイルしておく。ライブラリは、classes/orgディレクトリ下に作成される。Javaプログラムのコンパイル時に必要である。
$ cd /home/apache/tools/batik-1.7 $ build.sh compile ↓ライブラリ作成 batik-1.7/classes/org/*
ソース /home/apache/tools/batik-1.7/sources-png/SaveAsPNG.java 第1引数:SVGパス名 第2引数:PNGパス名 コンパイル $ cd /home/apache/tools/batik-1.7/sources-png $ ant ↓ classファイルは、classesディレクトリ下に作成される classファイルは、実行用transディレクトリにコピーされる 実行 $ cd ../trans $ go.png (java -Djava.awt.headless=true SaveAsPNG /home/apache/public_html/trans/GVT.svg /home/apache/public_html/trans/GVT.png)
ソース /home/apache/tools/batik-1.7/sources-png/SaveAsJPEG.java 第1引数:SVGパス名 第2引数:JPEGパス名 コンパイル $ cd /home/apache/tools/batik-1.7/sources-jpg $ ant ↓ classファイルは、classesディレクトリ下に作成される classファイルは、実行用transディレクトリにコピーされる 実行 $ cd ../trans $ go.jpg (java -Djava.awt.headless=true SaveAsJPEG /home/apache/public_html/trans/GVT.svg /home/apache/public_html/trans/GVT.jpg)
チュートリアルのコードのままでは、実行時にエラーが出るので、以下の点を変更した。
TranscoderInput()の引数に、URIではなく、InputStreamを渡すようにする。
//String svgURI = new File(args[0]).toURL().toString(); //TranscoderInput input = new TranscoderInput(svgURI); ↓ 変更 InputStream istream = new FileInputStream(args[0]); TranscoderInput input = new TranscoderInput(istream);
また、サイズを指定しないと一部分しか変換されないことがあるので、addTranscodingHint()で幅、高さ、リージョンを指定する。
ソースは以下の通り(JPEGの場合は、PNGTranscoderの代わりにJPEGTranscoderを使用すること)。
import java.io.*; import java.awt.*; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; public class SaveAsPNG { public static void main(String[] args) throws Exception { // Create the transcoder input. //String svgURI = new File(args[0]).toURL().toString(); //TranscoderInput input = new TranscoderInput(svgURI); //System.out.println(svgURI); InputStream istream = new FileInputStream(args[0]); TranscoderInput input = new TranscoderInput(istream); // Create the transcoder output. OutputStream ostream = new FileOutputStream(args[1]); TranscoderOutput output = new TranscoderOutput(ostream); // Create a PNG transcoder. PNGTranscoder t = new PNGTranscoder(); // Set width and height. int width = Integer.parseInt(args[2]); int height = Integer.parseInt(args[3]); Rectangle rect = new Rectangle(0, 0, width, height); t.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(rect.width)); t.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, new Float(rect.height)); // Set the region. t.addTranscodingHint(PNGTranscoder.KEY_AOI, rect); // Save the image. t.transcode(input, output); // Flush and close the stream. ostream.flush(); ostream.close(); System.exit(0); } }