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">



使用方法

ラスタライズ(SVGPNG/JPEG)のコマンド
バイナリ版とソース版で方法が異なる。

  • バイナリ版の例題の実行

  • 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の呼び出し
下記サイトにチュートリアルが載っているが、そのままの方法ではうまくいかない。例題のソースを実行してもエラーが出るので、ソースの一部を変更した。イメージのサイズを変更する方法などについては、ドキュメントを参照のこと。

  • 環境変数CLASSPATHの設定

  • batik.jarファイルは、Javaプログラムの実行時に必要となる。 環境変数CLASSPATHの設定に、batik.jarの記述を追加する。

    .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/*

  • PNG変換プログラムの例題の実行

  • ソース
      /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)

  • JPEG変換プログラムの例題の実行

  • ソース
      /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);
        }
    }