シミュレータの映像を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アニメのシーケンスの切り替え速さや
アニメーションの繰り返し回数なんかを設定していきたいなぁ
というわけで、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アニメのシーケンスの切り替え速さや
アニメーションの繰り返し回数なんかを設定していきたいなぁ