画像の表示


画像表示のメカニズム

JavaはGIFやJPEGファイルのロードや表示をサポートしています
GUIアプリケーションやアプレットとして、画像の表示は欠かせない要素の一つですね

今回はいよいよ、画像の扱いについて説明しましょう
実は、ソース上ではかなり簡単に画像を表示させることができます
しかし、その内部では複雑なクラスとインタフェイスの関係で成り立っているのです

画像ファイルの参照はjava.awt.Imageクラスを利用します
Imageクラス自体は、画像ファイルの参照などを提供するだけです
画像の生成に関する詳細な操作はjava.awt.Imageパッケージ下で行われます

AWT の画像操作に関して、プログラマが理解しなければいけない
重要なインタフェイスが三つ存在します

java.awt.image.ImageObserver
java.awt.image.ImageProducer
java.awt.image.ImageConsumer

イメージオブザーバーはイメージプロデューサーによる画像の読み込みを監視します
イメージプロデューサーはイメージコンシューマに渡す画像に関連づけられたビットを生成します
これらの詳しい内部動作について、今は詳しく知る必要はありません

Imageクラスのオブジェクトを作成するには、AppletクラスのgetImage()クラスを使用します

public Image getImage( URL url )
public Image getImage( URL url, String name )

このメソッドは指定されたURLオブジェクトの参照を持つImageオブジェクトを返します
上の書式の場合はurlが絶対パスになり、そのパスを返します

下の場合はurlが絶対パス(ベースURL)となり、nameがurlから見た相対パスとなります
通常はURLオブジェクトを直接生成することはありません
アプレットが置かれているURLを返すgetCodeBase()メソッドか
アプレットを呼び出したHTMLなどのファイルのURLを返すgetDocumentBase()メソッドを用います

public URL getCodeBase()
public URL getDocumentBase()

これらのメソッドを使用することで、動的に基本URLを参照できます
こうして得ることができたImageオブジェクトを画面に表示するには
GraphicsクラスのdrawImage()を呼び出します

public abstract boolean drawImage( Image img, int x, int y, ImageObserver observer )

これ以外にも、drawImage()はオーバーロードされていますが、それは後半で紹介します
まずは、画像ファイルの表示のメカニズムを知りましょう

imgはImageオブジェクトを渡します
メソッドはこのオブジェ句が参照している画像を展開します
xとyは、画像ファイルの左上部分を頂点としたx座標とy座標を指定します
observerは先ほど紹介したイメージオブザーバーの登録です

イメージプロデューサーが、画像のビットを生成しイメージコンシューマにビットを渡します
イメージオブザーバーはこれを監視するものです
例えば、どのようにダウンロードして表示するかというような操作に必要になります
java.awt.ComponentがImageObsarverインタフェイスを実装しているので
AWTの全てのコンポーネントがImageObsaverの引数に渡すことができます
import java.applet.Applet;
import java.awt.*;

/*      <applet code="App18.class" width="497" height="600">
        <param name="img" value="img/test.jpg">
        </applet>*/

public class App18 extends Applet {
        Image img;
        public void init() {
                setBackground(Color.white);
                setForeground(Color.black);
                img = getImage(getDocumentBase() , getParameter("img"));

        }

        public void paint(Graphics g) {
                g.drawImage(img , 0 , 0 , this);
        }
}
アプレット

これがJavaアプレットで表示した画像です
イメージオブザーバにはアプレット(this)を指定しています
当然ですが、あなたがこのプログラムをテストする時は画像ファイルがあるURL(パス)に変更してください

高度な画像操作をするには、インターフェイスの内容に熟知する必要がありますが
この場はdrawImage()について詳しく知りましょう

drawImage()メソッドには、いくつかの形式があります
一つ一つが特徴的なので、個別にできるだけ詳しく説明します
次の書式は、指定した長方形のサイズにスケーリングして表示します

public abstract boolean drawImage( Image img, int x, int y, int width, int height, ImageObserver observer )

widthとheightに、それぞれ長方形の横と縦のサイズを指定します
それ以外は、先ほどと同じですね
出力が完了していない場合はfalseを返します
import java.applet.Applet;
import java.awt.*;

/*      <applet code="App19.class" width="250" height="300">
        <param name="img" value="img/test.jpg">
        </applet>*/

public class App19 extends Applet {
        Image img;
        public void init() {
                setBackground(Color.white);
                setForeground(Color.black);
                img = getImage(getDocumentBase() , getParameter("img"));

        }

        public void paint(Graphics g) {
                g.drawImage(img , 0 , 0 , 250 , 300 , this);
        }
}
アプレット

縮小されていますね
アプレットの左上の0,0座標から横に250、縦に300の大きさの長方形に収めています

さらにdrawImage()メソッドの優れているのが、読み込み時に部分操作ができる点です
これは読み込む画像を画像元の一部分だけにしたり、同時に変倍したりすることができます
フィルターを使わなくても、多用すると思われる最低限のことはdrawImage()で可能なのです

public abstract boolean drawImage( Image img, int dx1, int dy1,
int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer )

かなり長い引数ですね
ですが、内容はこれまでの作業の繰り返しで、長方形を選択します
dx1,dy1は出力先の原点、dx2,dy2は出力先の長方形のサイズ
sy1,sy2は元画像の原点、sy1,sy2は元画像の長方形のサイズです

元画像から、指定されたサイズを切り抜くように読み取り
それを指定された長方形のサイズでコンポーネントに出力します

ここでもうひとつ、Imageクラスの便利なメソッドも覚えておきましょう
画像ファイルを扱うのに、渡される画像が動的に変化する場合はそのサイズを予想できません
Imageクラスのメソッドの中に画像のサイズを返すメソッドがあるのでこれを使いましょう

public abstract int getHeight( ImageObserver observer )
public abstract int getWidth( ImageObserver observer )

observerには、ImageObseverインタフェイスを実装したコンポーネントを渡します
つまり、画像ファイルの読み込みを待機するオブジェクトです

getHeightは縦サイズ、getWidthは横サイズを返します
ただし、読み込み中などの理由で幅が不明の場合は-1を返します
import java.applet.Applet;
import java.awt.*;

/*      <applet code="App20.class" width="300" height="300">
        <param name="img" value="img/test.jpg">
        </applet>*/

public class App20 extends Applet {
        Image img;

        public void init() {
                setBackground(Color.white);
                setForeground(Color.black);
                img = getImage(getDocumentBase() , getParameter("img"));
        }

        public void paint(Graphics g) {
                g.drawImage(img , 0 , 0 , 300 , 300 ,
			 0 , 0 ,img.getWidth(this) / 2 , img.getHeight(this) / 2  , this);
        }
}
アプレット

さらに今までと同じもので、イメージの背景色を選択することもできます
透過ファイルを扱うときなどのために、知っておくべきでしょう

public abstract boolean drawImage( Image img, int x, int y, Color bgcolor, ImageObserver observer )
public abstract boolean drawImage( Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer )

public abstract boolean drawImage( Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer )

bgcolorに、Colorオブジェクトを指定します
それ以外は、これまで紹介した形式と同じものです


画像を反転させる

画像サイズを変えて表示する方法はわかりました
ですが、画像を扱ったプログラムの経験が無い人は以外と知らないかもしれませんが
Javaのような変倍をメソッドとして扱えるプログラムの場合は簡単に画像を反転させることができます

画像を反転させるのに、特別なメソッドを使うことはありません
相変わらずdrawImage()メソッドだけを使用します
この方法がわかれば、90度反転や180度反転といった画像操作が簡単になります

実は始点と終点を反転させることで、画像は反転します
つまり、0×0座標から300×300座標の画像なら、300×300を頂点として0×0まで出力すれば上下左右に反転します
左右だけの反転ならば、300×0を頂点として0×300まで出力すれば左右が反転します
import java.applet.Applet;
import java.awt.*;

/*      <applet code="test.class" width="600"height="300">
        <param name="img" , value="img/test.jpg">
        </applet>
*/

public class test extends Applet {
        Image img;

        public void init() {
                img = getImage(getDocumentBase() , getParameter("img"));
        }

        public void paint(Graphics g) {
                g.drawImage(img , 300 , 0 , -300 , 300 , this);
                g.drawImage(img , 600 , 300 , -300 , -300 , this);

        }
}
この方法は、比較的新しいJavaです
アプレット(ブラウザに搭載されているJVM)の場合はまだ、その多くが未対応の状況です
このプログラムを実行する場合、最新のJDKに付属しているアプレットビューワか
アプリケーション(アプリケーションのGUI建築は後記)として実行してください



前のページへ戻る次のページへ