ソフトウェア開発したい日記

「面白い!」と思った頭の体操や、数学の問題を載せていきます
その他ロードバイクででかけた先の写真や、ソフト開発のメモ等

Javaでアニメーションgifの書き出し

2010年03月27日 21時10分55秒 | ソフト開発日記
シミュレータの映像をgifアニメで書き出したい。
というわけで、gifアニメの作成方法のメモ。

IDEは相変わらずNetBeansで。

まずは適当な場所で変数等宣言。

public static BufferedImage buffer;
Iterator it = ImageIO.getImageWritersByFormatName("gif");
ImageWriter iw = it.hasNext() ? (ImageWriter) it.next() : null;
File outfile = new File("書き出すファイルのパス.gif");

録画ボタンを押したときのアクションに、次のようなソースを入れる。

try {
 ImageOutputStream ios = ImageIO.createImageOutputStream(outfile);
 iw.setOutput(ios);
 iw.prepareWriteSequence(null);
} catch (IOException ex) {ex.printStackTrace(); }
page = 0;
rec = true;

Threadクラスを継承し、run()メソッドをオーバーライドしたクラスの
whileループの中の、repaint()メソッドの後に次のようなソースを挿入。

if (rec) {
 try {
  Thread.sleep(10);
  iw.writeToSequence(new IIOImage(buffer, null, null), null);
  page++;
  if (page > MAX_PAGE || stop) {
   iw.endWriteSequence();
   rec = false;
  }

 } catch (IOException ex) { ex.printStackTrace();}
}

これで、シーケンスの数がMAX_PAGEになるか、boolean型のstopがtrueに
なるまでiwに書き続け、iw.endWriteSequence()で終わりの1枚を書き出してgifアニメの完成。

それから、描画先はすべてBufferedImageのbufferにする必要があり
オーバーライドするpaintComponentメソッドは次のように書く。


public void paintComponent(Graphics gBuf){
 super.paintComponent(gBuf);
 if(Mechanics.buffer == null){
  Mechanics.buffer = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
 }
 Graphics g = buffer.createGraphics();

/* ここからBufferedImageに描画していく */
 g.drawRect・・・

/* 最後にBufferedImageに描画されたものを表示 */
 gBuf.drawImage(buffer, 0, 0, this);
}


こんな感じかなぁ。一応できたけれど、上のほうで書いた
Thread.sleep(10);くらい処理待ちさせないと、repaint()による描画が完了する前にシーケンスに書き込むっぽくて
チカチカしたgifアニメになってしまう。
FPS調整はしているけども、シーケンス書き込む処理が重いせいっぽい。
自分のパソコンがちょっと古いってのもあるだろうけど・・

とりあえず一応gifアニメ生成できたってことでよしとして
今後はより最適な書き出し方や、gifアニメのシーケンスの切り替え速さや
アニメーションの繰り返し回数なんかを設定していきたいなぁ