グラフィックスを扱う |
前のページの動画では 2 つのことに気づかれたはずである。
- イメージがロードされている間に、プログラムはいくつかのイメージを部分的 に表示し、それ以外はまったく表示しなかった。
- イメージのロードに長い時間を要した。
部分的なイメージが表示される問題は、 MediaTracker クラスを使用して簡単に修正 できる。 MediaTracker はまた、イメージのロード時間も短縮できる。 イメージのロードが遅いという問題に対処する別の方法は、イメージ形式を何らかの 形で変えることである。 このページでは、これを行うときのアドバイスをいくつか述べる。
MediaTracker を使用してイメージをダウンロードし、イメージの表示を遅らせ る
MediaTracker クラスでは、イメージグループのデータを簡単にダウンロードし、イ メージがいつ完全にロードされたかを知ることができる。 イメージのデータは通常、イメージが最初に描画されるまでダウンロードされない。 イメージグループのデータを非同期に事前ロードするよう要求するには、 論理型引数をとる checkID() と checkAll() の書式で、その引数を true に設定すれば よい。データを同期的にロードする (データの到着を待機する) には、 waitForID() と waitForAll() メソッドを使用する。 データをロードする MediaTracker のメソッドは、データのダウンロード用のバックグラウンドスレッドをいくつか使用し、速度を速めている。
イメージローディングの状態を確認するときは、MediaTracker の statusID() と statusAll() メソッドを使用できる。 ロードが終わっていないイメージデータがあるかどうかを確認するだけなら、 checkID() と checkAll() メソッドを使用できる。
MediaTracker の waitForAll() と checkAll() メソッドを使用している、アプレット例の修正バージョンも参照でき る。 すべてのイメージが完全にロードされるまで、このアプレットはただ "Please wait..." というメッセージを表示するようになっている。 背景イメージをただちに描画し、動画化するイメージの描画は遅らせる例については 、 MediaTracker のマニュアル を参照する。
ここで、動作中のアプレットを示す。
使用中のブラウザは 1.0 Java アプレットを実行することができない。実行できた場合は、デュークが手を振っている様子が見られる。
以下に、イメージ表示を遅らせるために MediaTracker を利用するよう変更したコードを示す。 変更個所はボールド書体で記述する。
...//インスタンス変数を宣言する。 MediaTracker tracker; ...//init() メソッドで: tracker = new MediaTracker(this); for (int i = 1; i <= 10; i++) { images[i-1] = getImage(getCodeBase(), "../../../images/duke/T"+i+".gif"); tracker.addImage(images[i-1], 0); } ...//run() メソッドの冒頭で: try { //イメージのダウンロードを開始し、ロードが終わるまで待機する。 tracker.waitForAll(); } catch (InterruptedException e) {} ...//update() メソッドの冒頭で: //すべてのイメージがロードされていない場合は、背景をクリアし、 //状態文字列を表示するだけである。 if (!tracker.checkAll()) { g.clearRect(0, 0, d.width, d.height); g.drawString("Please wait...", 0, d.height/2); } //すべてのイメージがロードされていれば描画する。 else { ...//前のコードと同じ...イメージローディングのスピードアップ
MediaTracker を使用するかどうかにかかわらず、URL を使ったイメージローディン グ (アプレットは通常この方式で行う) は時間のかかることが多い。 時間のほとんどは、HTTP 接続の開始にとられている。それぞれのイメージファイル は個別の HTTP 接続を必要とし、それぞれの接続を開始するのに何秒かかかってしま うのである。 このようなパフォーマンスへの悪影響を回避するには、複数のイメージを 1 つのフ ァイルに結合することが重要である。 また、ある種の圧縮方式、特に動くイメージのために用意された圧縮方式を活用することで、パフォーマンスをさらに上げることが可能となる。
1 つのファイルにイメージを結合する簡単な方法は、イメージストリップを作成する ことである。イメージストリップとは、複数のイメージを連続して納めたファイルである。 イメージストリップの例を次に示す。
jack.gif :
イメージストリップからイメージを描画するには、まず、クリップ領域を 1 つのイ メージのサイズに設定する。その後、(必要があれば) 左にシフトさせて、望みのイ メージだけがクリップ領域に現れるようにイメージストリップを描画する。 次に例を示す。
//imageStrip はイメージストリップを表す Image オブジェクトである。 //imageWidth はストリップ内の個々のイメージのサイズである。 //imageNumber は描画するイメージの数 (0 から numImages まで) である。 int stripWidth = imageStrip.getWidth(this); int stripHeight = imageStrip.getHeight(this); int imageWidth = stripWidth / numImages; g.clipRect(0, 0, imageWidth, stripHeight); g.drawImage(imageStrip, -imageNumber*imageWidth, 0, this);さらに高速なイメージローディングを望む場合は、 イメージ圧縮方式、特にフレーム間の圧縮を実行する Flic のような圧縮法式を検討する。
グラフィックスを扱う |