LoginSignup
0
2

More than 3 years have passed since last update.

Processingから外部プロセスを実行する

Posted at

この記事の内容

Processingから外部プロセスを実行する方法についての覚え書き.

環境

OS: Windows 10 Home (1909)
Processing: 3.5.4

参考

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/ProcessBuilder.html
https://www.ne.jp/asahi/hishidama/home/tech/java/process.html

外部プロセスの実行

Runtimeクラスを使う方法が紹介されていることがあるが,JDK1.5以降はProcessBuilderクラスを用いるのがよいとされている.外部プロセスでファイルを扱う場合,実行時の作業ディレクトリを指定することで,ファイルへのアクセスが容易になる.
ProcessBuilderクラスのコンストラクタには,実行ファイルと引数(複数OK)を与える.
ProcessingのdataFile()関数はdataフォルダに入っている引数で与えられた名前のファイルのjava.io.Fileインスタンスを返すものであり,引数に空文字列を与えることでdataフォルダそのものを得ることができる.
以下の例はPythonスクリプトの実行例である.スクリプトsample.pyに引数testdata.csvを与えて処理を開始している.

String python_exe = "py"; // py.exeにはpathが通っている
String python_script = "sample.py";
String data_filename = "testdata.csv";
Process process;

void execExternalProcess() {
  try {
    ProcessBuilder pb = new ProcessBuilder(python_exe, python_script, data_filename); // 実行するコマンドと引数列
    pb.directory(dataFile("")); // 実行時のディレクトリを指定
    process = pb.start(); // 実行
  } catch (Exception e) {
    println(e);
  }  
}

外部プロセスの終了待ち

プロセスの状況はProcessクラスのisAlive()メソッドで知ることができる.プロセスが実行中は待機メッセージを表示し,プロセスの処理が終了したら結果を得て(ファイル読み込みなど)処理を進めるといったことができる.
以下は外部プロセスが画像を生成する場合の例である.画像生成のためのプロセスが終了するまではメッセージと処理中であることを示すメッセージとアニメーションを表示し,処理が終わったら画像を読み込んで表示している.

String image_filename = "result.jpg";
PImage img;

void draw() {
  if (img == null) { // 画像がまだ読み込まれていない場合
    background(0);

    if (!process.isAlive()) { // プロセスが実行中ではない(つまり,終了した)
      File file = dataFile(image_filename);
      if (file.exists()) { // 生成された画像ファイルがあれば読み込む
        img = loadImage(image_filename);
        set(0, 0, img); // 表示する
      } else { // プロセスが終了したが画像無し→多分,生成に失敗した
        translate(10, 40);
        noStroke();
        fill(255);
        textSize(32);
        text("external process failed", 0, 0);
      }
    } else { // 無ければ画面にメッセージ表示
      translate(10, 40);
      noStroke();
      fill(255);
      textSize(32);
      String s = "making images...";
      text(s, 0, 0);

      // ぐるぐるを表示
      translate(textWidth(s) + 20, -10);
      rotate(TWO_PI * millis() / 1000);
      final int n = 12;
      for (int i = 0; i < n; i++) {
        fill(255 * i / n);
        circle(12, 0, 4);
        rotate(TWO_PI / n);
      }
    }
  } else { // 画像読み込み済みの場合
    set(0, 0, img);
  }
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2