GIFアニメーションのフレーム切り替え検知


最近ではFlashなどによるアニメーションもずいぶんと増えてきましたが、ごく単純なアニメーションの繰り返しなら「GIFアニメーション」がもっとも多用されていることでしょう。単に複数のイメージをフレームに持つGIFファイルを作成するだけで、特殊なプラグインなども使わずWebページなどでアニメーションできるという利点は他に代えがたいものがあります。

JavaでもこのGIFアニメーションを利用することはできます。ごく普通のイメージと同様にファイルからImageを読み込み、drawImageで描画するだけでちゃんとアニメーション表示を行ってくれるのです。ですから、単純にGIFアニメーションを表示するだけならば、特に何も考えることはありません。が、せっかくJavaのプログラム内で利用するのですから、もっとGIFアニメーションをうまく利用する方法を知りたいものですね。

例えば、GIFアニメーションの再生をON/OFFする、というのはどうでしょう? アニメーションをプログラム内から再生/停止できたら便利ですね? これを行うためには、まず「イメージの更新がどのようにJavaの中で伝えられ確認されるか」ということを理解しないといけません。

Javaでは、Imageが構築される際、その更新状況などの状況を受け取り管理するためのものとして「ImageObserver」というものが用意されています。drawImageなどを実行する際、たいていは一番最後の引数にthisを指定したと思います。これが、「ImageObserverのインスタンス」を指定するものだったわけです。このようにすることで、その表示の更新状況などの情報をImageObserverに渡すようになっていたのです。通常、FrameなどのコンテナクラスにはあらかじめImageObserverがimplementsされています。このため、普通はthisを引数に指定していたのですね。
Imageが構築される際、その更新情報はImageObserverに送られ、imageUpdateメソッドが呼び出される。

このImageObserverには、「imageUpdate」というメソッドが用意されています。Imageが構築される際、このメソッドが呼び出され、イメージの更新に関する情報が渡されます。このメソッドはbooleanを返値として持っています。引き続き更新情報を要求する必要がある場合にはtrueを、その必要がなければfalseを返します。これにより、trueが返された際には再度何らかの更新が行われた際にimageUpdateが呼び出され表示の更新が行われますが、falseが返された場合には以後の情報取得は不要と判断され、何らかの更新が行われても表示の更新はなされなくなります。

GIFアニメーションの場合、フレームが切り替わる際に「ImageObserver.FRAMEBITS」という情報が渡されます。これはマルチフレーム・イメージの新たに用意されたフレームのイメージが再描画できるようになったことを示します。imageUpdateが呼び出された際、引数に渡されたフラグ情報にこのFRAMEBITSのフラグが含まれていたならば、それは「次のフレームを描画する準備が整いましたよ」ということを意味するわけです。ここでreturn trueすれば、表示が更新され、再び次のフレームが準備できた際にまたimageUpdateが呼び出されるようになります。falseが渡された場合には、以後はimageUpdateは呼ばれなくなり、当然フレームの切り替わり処理もされなくなるというわけです。