実験室 |
画像ファイルのロード |
|||||||||||||||||
画像ファイルをロードするには |
|||||||||||||||||
デジカメがこれだけ普及してくると、普通の人でも JPEG などのファイルを扱うことが増えてきていると思います。 もちろん、Java でも画像を扱うことができます。Java が登場した頃は Applet でアニメーションというのが非常にもてはやされました。そのほとんどが複数の画像ファイルをロードして、それをとっかえひっかえ描画するというものでした。 さて、Java 2 もバージョンが 1.4 までくると、画像の扱いもずいぶん変化しました。例えば、画像ファイルのロードだけでも次の 4 種類ぐらいあります。
ここにはあげていないのですが、JIMI というライブラリもあります。しかし、これは JDK 1.1 の頃のオプショナルライブラリで、現在はサポートされていないため、入れていません。 それぞれの方法のパフォーマンスや使い方などをまとめてみましょう。
|
java.awt.Toolkit |
||||||||||||||
まずは JDK 1.0 の頃から使われている java.awt.Toolkit クラスを利用した画像ファイルのロードです。 このクラスを利用した場合の特徴は次の通りです。 特徴
使用法
Applet のサンプル
このサンプルは Applet なので、画像ファイルの URL には CodeBase を利用しています。
Toolkit#getImage はイメージのロードが終了しなくてもメソッドから抜けてしまいます。ようするにロードは別のスレッドで行っているわけです。これはこれでいいのですが、いざ描画するときになって画像がない場合には困ってしまいます。 こんなときに一緒に使用するのが java.awt.MediaTracker クラスです。サンプルは ToolkitImageLoader2 クラスです。
MediaTracker クラスは読み込む画像ファイルに ID をつけて、ロードが終わっているかどうかを調べたり、ロードが終わるまで wait したりできます。ToolkitImageLoader2 クラスでは init メソッドで MediaTracker オブジェクトにロードする画像を ID つきで登録します。
MediaTracker クラスのコンストラクタの引数は java.awt.Component オブジェクトです。Applet の場合は Applet 自体が Component の派生クラスなので、Applet オブジェクト自身を引数にしてしまいます。 もし、Component オブジェクトがなければ、ダミーの Component オブジェクトを使います。Component クラスは abstract クラスなので、そのままでは new できないので、Component クラスを派生させた無名クラスを使用します。 GUI はないけど、イメージだけ扱いたい場合などにこの方法が使えます。
javax.swing.ImageIcon クラスも Toolkit クラスと MediaTracker クラスを使用して画像ファイルをロードしています。ImageIcon クラスも上述の方法と同じ方法で MeiaTracker オブジェクトを生成しています。
|
JPEGImageDecoder |
|||
JPEGImageDecoder クラスはコアライブラリとは異なり、Sun 独自のクラスになります。その特徴は次のとおりです。 特徴
使用法
JPEGCodec の static メソッドの createJPEGDecoder を使用してオブジェクトを生成し、decodeAsBufferedImage メソッドでロードします。ロードが終了するまで、ブロックされるので Toolkit クラスを使用したときのように MediaTracker クラスなどを使用した wait を行う必要はありません。 逆にいえば、ロード中に他のこと (例えば、ロード中であることをしめすプログレスバーを表示するとか) は別スレッドにする必要があります。
|
Image I/O |
|||
Image I/O は J2SE 1.4 からコアに含まれるようになりました。もともとは Java Advanced Imaging の一部だったのですが、独立して画像のロード・セーブに特化したものです。 特徴
使用法 ここでは一番基本的な方法だけを示しておきます。詳しい使用法は J2SE 1.4 の新機能紹介の Image I/O を見てください。
|
Java Advanced Imaging API (JAI) |
|||
JAI は画像処理のためのライブラリで、フィルタリングやコンボリューションなど画像処理に欠かせない機能を提供しています。また、Java 2D のプッシュ型のイメージングではなく、プル型であることも特徴です。 JAI の画像ファイルのロードは Image I/O を呼び出す形になりますが、それをそのまま使っているわけではないようです。また、使い方はかなり違います。 特徴
使用法 RenderedOp オブジェクトを生成する部分まで示して起きます。この後は、アプリケーションによって扱いがかなり異なると思うので。
|
実験、実験 |
|||||||||||||||||
上述した 4 種類の方法を使用してパフォーマンスを測定してみました。 JAI は画像のロードだけではあまり意味がないので、読み込んでそれを表示するまでの時間で計測しました。計測に使用したテスト用プログラムは ImageLoadingTest.java。測定条件は J2SDK, SE, v1.4.1_01, Athron 800MHz, RAM 512MB, Win 2000 です。 結果
sun.com.image.codec.jpeg はネイティブで記述されているためか、高速です。ただ、いつ使えなくなるか分からないところが困りもの。 Toolkit と Image I/O はほぼ同じようなパフォーマンス。私だったら、J2SE v1.4 以上であれば Image I/O、v1.4 以下だったら Toolkit を使用すると思います。Image I/O はサムネイルや複数イメージ (例えばアニメーション GIF など) も扱えるなど、高機能であるのがその理由です。 JAI は画像の読み込みのためのAPI ではないので、遅いのは当然かもしれません。JAI で画像ロードだけを使うという使い方はかなり邪道なので、イメージングの一環として使うにはいいと思います。 ここでは、ロードの時間だけを測定しましたが、メモリの使用量も重要になると思います。 (Apr. 2003) |
|