かつてJavaのGUIをベクトルデータとしてスクリーンショットを撮る と題して、JavaといってもSwing GUI限定ではあるが、 スクリーンショットを PostScript で出力するアイデアを紹介した。 しかし、実際に実装するとテキストがパス化されていたりなど、 細かい点で問題が残った。

その結論で、Batikを使ってよりよい出力ができるのではないかと示唆した。

半透明などをベクトルデータとして出力できない問題を解決するには、グラフィックコンテクストの描画命令から SVG などの出力を行うものが必要となるだろう。[4]

[4] SVG Generator: SVGGraphics2D, The Apache Software Foundation

というわけで、Batik の How to use SVGGraphics2D というページを参考にして作ってみた。

つまり、前回のソースに対して、以下のような document に描画情報を出力した後ファイル出力するコードをねじ込んだ。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.getDOMImplementation().createDocument("http://www.w3.org/2000/svg", "svg", null);
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
Printable printable = createPrintable();
PageFormat pagefmt = new PageFormat();
for (int i = 0; printable.print((Graphics)svgGenerator, pagefmt, i) == Printable.PAGE_EXISTS; i++) {
    // do nothing
}
svgGenerator.stream(filewriter, true);

これはなかなか強力で、テキストがテキストのままで出力された。 テキスト描画がそのまま<text>要素でSVGに変換されていた。

SwingSet2 のSVGスクリーンショットを inkscape で開いたところ。テキスト選択可能。

しかし、問題もかなりあって、Exception が出て出力できないことが しばしばある。 しかも org.apache.batik.ext.awt.image.codec.png.PNGImageEncoder.encodeRuntimeExceptionとか一筋縄で行かなさそう。 (そして筆者はそれ以上の原因追求はおこなっていない)

さらに、そもそもの問題であるが、Batik は 2008年 にリリースされた バージョン 1.7 から安定バージョンが出ていない。 つまりメンテナンスが積極的に行われていない感が拭えない。 もっとも、開発レポジトリ(subversion) http://svn.apache.org/repos/asf/xmlgraphics/batik/trunk/ のログを見るとまだ手を入れられているので、 trunkから落としてきて最新trunkビルドで試したほうがよかったかもしれない。 (が、ビルドが面倒なので確認していない。)