※本記事はJava6リリース前に書かれたため、現在の状況と異なった内容が書かれています。Java6では、GIFの保存が標準でサポートされたため、別途pluginを導入することなく、Image I/O経由でGIFを保存できます。
はじめに
Javaが広く実務に使われるようになって、もうずいぶんになります。アプリケーションサーバの構築など、サーバ側で使われることが多いのですが、その対極の用途にも利用されています。携帯端末のアプリケーション、というより、携帯電話向けのゲームの作成です。特に日本では、対応端末の展開が進んでいることもあって、よく使われています。
一般的に、実務でアプリケーションを作る場合、ユーザーにサービスを提供するアプリケーションだけでなく、その周辺のツールとなるプログラムが必要になります。サービスのためのデータを用意したり、顧客情報を管理したり、ちょっとしたツールを書いた経験が皆さんにもあるでしょう。
ゲームを作成する際にも、そのようなツールを作ることがあります。代表的なのが画像を加工するツールです。画像そのものは絵描きさんからもらいますが、特定のロジックに基づいて画像を加工することがあり、この場合は、手作業でやるよりもプログラムを作って自動処理した方が都合が良いのです。
Javaでアプリケーションを作っているのであれば、ツールもJavaで書いた方が楽でしょう。アプリケーションとツールでコードを共有できるかも知れませんし、同僚全員が読み書きできることが保証されます。
携帯電話向けのゲームでは、画像形式として「GIF」がよく使われます。Javaがサポートする画像形式の1つであり、透過が可能で、ファイルサイズを小さくできるからです。当然、JavaでGIFを扱うツールを作ることになります。しかし、これが、一筋縄でいかないのです。
対象読者
Javaを使って画像を扱う可能性のある方。携帯電話向けのプログラムや、Webアプリなどに携わっている方。
必要な環境
コードの動作確認は、以下の環境で行っています。
- Windows 2000 SP4
- J2SE Development Kit 5.0 Update 8
- NetBeans 5.0 日本語版
- gif-plugin
- FreeHEP Java Library 1.2.2
他のOS上でも、本稿に示されたものと同じ動作をするはずです。
ただし、NetBeansが使える環境でなくても、サンプルプログラムの実行とソースを読むことはできますので、NetBeansは必須ではありません。
生き残るGIF
画像ファイルのデータ形式の1つであるGIFは、1987年、米CompuServe社によって、自社が運営するパソコン通信サービスのために開発されました。当時の低速な通信回線に合わせてファイルの大きさを抑えるため、パレットを用い、圧縮をサポートしていました。さらに、複数の画像をパックしたり、それらを素材にアニメーションを表現できる拡張が施され、1990年に現在の仕様となっています。当時のCompuServeは、世界最大規模のパソコン通信サービスであったため、GIFも広く使われるようになっていきました。その後の1993年、画像を表示できる最初期のWebブラウザ「NCSA Mosaic」に採用されると、インターネットにおける標準画像形式の地位を得ました。
しかし、圧縮方式として採用していたLZWに、米Unisys社の特許があり、Unisys社の特許戦略の転換によって、フリーソフトウェアに影響が及ぶと、GIFを扱うフリーウェアは姿を消してしまいました。特にUnisys社が強い姿勢を表明した1999年から、日本で特許の失効する2004年までは、商用ソフトを使う以外ありませんでした。
LZW特許問題による5年の空白は、GIFをインターネットにおける標準画像形式の地位から引き摺り下ろすはずでした。256色しか使えない表現力の限界も指摘されており、GIFに替わる安心して使える画像形式として、PNGを支持する気運が高まったからです。期待されたPNGですが、主役にはなれませんでした。世界で最も普及しているWebブラウザで、完全にはサポートされていないからです。そして、嵐は去り、GIFは息を吹き返しました。
インターネット技術との親和性を考慮して構築されたJavaの標準ライブラリにおいても、GIFは最初期から標準でサポートされてきました。Webブラウザ、Javaを利用する携帯電話においても、データが小さくなる特徴もあって、GIFは最初期から標準でサポートされています。
Image I/O
Java 1.4から、画像データを一元的に扱う仕組み「Image I/O」が用意されました。Image I/Oでは、画像形式に関わらず画像を読み書きするための汎用的な枠組みを用意し、pluginによって個々の画像形式に対応する仕組みになっています。仕様に基づいてpluginを書けば、勝手に作った独自画像形式であっても、Image I/Oの流儀に基づいて読み書きできるわけです。
では、既にpluginが用意されている標準の画像形式には、どんなものがあるでしょうか? Image I/Oに関する文書『J2SE 5.0でのJava ImageI/Oの新機能』を見てみます。
J2SE 5.0では、javax.imageioのすべての実装により、JPEG、PNG、BMP、WBMPイメージの読み込みおよび書き込み、また、GIFイメージの読み込みのサポートが提供されます。
あれ、GIFは書き込めないの? そうなんです、書き込めないんです。当時、LZW特許に抵触しないGIF読み込みアルゴリズムが考案されていたため、読み込みだけはサポートされました。
Image I/Oが導入されたJava 1.4は、2001年にリリースされました。つまり、LZW特許問題による空白の5年の真っ只中にリリースされたわけです。米SunMicrosystems社は、Unisys社に特許使用料を支払わないことを選択しました。理由はいくつか考えられます。ダウンロード数に比例してライセンス料が請求される仕組みだったらしいので、Javaを有料化しないと特許使用料を払えなかったであろうこと。米Microsoft社がライセンスを取得したにも関わらず、特許を使用したWindowsの機能を呼び出すアプリケーションに、別途ライセンスが必要とされたこと。Javaを利用する開発者にとって、何1つ良い事が見当たらなかったのです。
ちなみに、現在、開発が進められているMustang(Java SE 6)でも、GIFの書き込みはサポートされない模様です。SunMicrosystems社にとっては、GIFは過去のものであり、PNGを使って欲しいというメッセージなのでしょう。でも日本では、携帯電話を中心に、Javaのビジネスのど真ん中にGIFがあります。
個人的な感想ですが、NetBeansの操作感は、Delphiに非常に近く感じます。ちゃんと使い始めて、まだ間もないのですが、手に馴染む感じがします。Eclipseでは感じられなかった感覚です。
コード補完や、リフレクションなど、最近当たり前になった機能は、昔のDelphiになかったので、その分は便利になっています。しかし、まだDelphiレベルに達していない部分もいくつかあります。例えば、参照するドキュメントが純正のJavadocとなっていて、NetBeansが独自に提供するイベントハンドラについて理解し難い点が挙げられるでしょう。
でも、かなり気に入っています。実は、Java Computing 2005 Springで、きしだなおきさんの講演を聞いて、使ってみようと思ったんです。いいキッカケをもらいました。