ファイルによる画像データ授受 #1

標準入出力での画像の受け渡しはいろいろと面倒なことがあるので、
Javaが実装された環境であれば使えることが期待されるファイルシステムを利用する。

import java.io.*;
import javax.imageio.ImageIO;

public class GnuplotUser6 {
    private static final String GNUPLOT = "/usr/bin/gnuplot";

    public static void main(String[] args) throws IOException, InterruptedException {
        Process p = new ProcessBuilder(GNUPLOT, "-").start();
        try (PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(p.getOutputStream())))) {
            String name = "gnuplotuser6temporary.png";
            out.println("set terminal png");
            out.println("set output \"" + name +"\"");
            out.println("plot sin(x)");
            out.println("set output");
            out.flush();
            Thread.sleep(1000); // ad hoc
            try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(name))) {
                System.err.println(ImageIO.read(in));
            }
            new File(name).delete();
        }
        p.waitFor();
    }
}

gnuplot側でset outputによって明示的に画像の出力先ファイルを指定して、
Java側でそのファイルを開いて読み込んでいるだけである。
この画像ファイルはカレントディレクトリに作成され、
もしその名前のファイルが既に存在していれば上書きされる。
このファイルは画像の授受のための一時的なものであるので、
画像オブジェクトが生成されたら削除するようにしてある。

このコードにはあまりいい感じでない部分がある。
gnuplotへの命令を送出した後、ファイルを開いて読み込み始める前に、
一秒間処理を停止している部分がある。
これはgnuplotが処理を行って画像ファイルを作成し始めるよりも先に、
Javaがまだ存在していないファイルを開こうとして例外を吐くことを防ぐためである。
一秒という時間には根拠がなく単に自分の環境での十分な時間というだけである。
実は長すぎるのかもしれないし、環境しだいではそれは短くて失敗するかもしれない。