AWT イメージレンダリング API


最終更新日: 1996 年 10 月 30 日

問題

現在 AWT Graphics オブジェクトには、オプションのスケーリングとオプションのバックグラウンドカラーでイメージ全体をレンダリングする、4 つのメソッドを持っています。

イメージ全体のサブセットを、Graphics オブジェクトのクロッピングフィルタまたはクリッピング機構を使用せずにレンダリングする方法はありません。この状況に加えて、Graphics オブジェクトのクリップ属性がさらに制限された値にしか設定できず、拡張したり以前のクリップ領域に復元したりできないという事実があります。

イメージを拡大縮小する既存のメソッドもまた、プログラマがイメージを負のサイズに拡大縮小するなどの方法によって水平または垂直にフリップすることを許しません。ほかの任意のイメージ操作がサポートされていない場合でも、フリッピングの欠如は重要な問題です。これは、すでにサポートされている拡大縮小アルゴリズムに対してわずかな算術的修正を行うことで簡単に制御できるからです。

矩形の引数を取る既存の Java インタフェースのほとんどは、負の幅と高さの値を空の矩形を意味するものとして扱います。既存の drawImage メソッドは、イメージを負のサイズに拡大縮小するように指定された場合に、イメージフリッピングを許容できた可能性はあります。しかし、それは他で見られる空の負の矩形プロトコルと衝突した可能性があります。負の値を null 操作として扱う (論証的には正当) 代わりに、既存の drawImage メソッドは負の幅と高さの値を「比例値」として考えます。つまり、値の 1 つが負の場合、元のイメージの縦横比を維持するために、適当な値が他の負でない数量に基づいて代替されます。両方とも負の場合、イメージは元のサイズとスケールで描画されます。この動作は、いくつかのブラウザが HTML <img> タグで幅と高さ属性が仕様に合っていない場合の処理方法との互換性を考慮して設計されました。本質的には、イメージを負の幅または負の高さに拡大縮小することは、イメージを幅または高さを指定せずに拡大縮小することと同じと考えられ、デフォルト値を取得するために、標準の「比例」アルゴリズムが適用されます。

新しいイメージレンダリング API

この問題を解決するために、2 つの新しいメソッドが AWT Graphics クラスに追加され、完全なスケーリング、フリッピング、クロッピング、イメージレンダリング機能を提供します。新しいメソッドは次の 3 つです。
	drawImage(Image img,
		  int dx1, int dy1, int dx2, int dy2,
		  int sx1, int sy1, int sx2, int sy2,
		  ImageObserver observer)
	drawImage(Image img,
		  int dx1, int dy1, int dx2, int dy2,
		  int sx1, int sy1, int sx2, int sy2,
		  Color bgcolor, ImageObserver observer)

これらの新しいメソッドで注目すべき点は、以前の drawImage() メソッドが、非同期スレッドで raw イメージを再読み込みすることにより、画面イメージの表現をまったく新しく作成する一方、新しいメソッドは拡大縮小されていないイメージバージョンからのピクセルを常に使用し、画面に描画することです。結果として、2 つの新しいメソッドは、イメージのフルサイズバージョンが、MediaTracker または他のイメージステータス API が示すようにあらかじめロードされ変換されている限り、同期的に完了します。

新しいメソッドの座標指定におけるもう 1 つの変更点は、ソースと転送先矩形を定義するために 2 つの座標を使うことです。負の幅と高さは残りの Java API で元々の意味を持ち続けるため、新しいメソッドは新しい座標対指定を使用し、どの次元がフリップされるかを明示的に制御できるようにします。この新しいシステムは、ユーザのマウスドラッグに従ってイメージのコーナーを追跡するアプリケーションにとって便利なものです。ドラッグの開始と終了座標を x、y、w、h の形式に分解する必要はありません。

サンプルコード

イメージクロッピングを実行するための古い API の使用方法を示すサンプルコードを、次に示します。


    import java.awt.*;
    import java.applet.*;

    public class ImgCropExample extends Applet {
	Image bgimg, img2;
	public void paint(Graphics g) {
	    // Draw a background image
	    g.drawImage(bgimg, 0, 0, this);
	    // Draw the upper left 100x100 portion of another image at 10,10
	    Graphics g2 = g.create();
	    g2.clipRect(10, 10, 100, 100);
	    g2.drawImage(img2, 10, 10, this);
	    g2.dispose();	// reclaims resources more quickly
	    // Now continue drawing with original clip area
	    g.fillRect(0, 0, 10, 10);
	}
    }

イメージクロッピングを実行するための新しい API の使用方法を示すサンプルコードを、次に示します。


    import java.awt.*;
    import java.applet.*;

    public class ImgCropExample extends Applet {
	Image bgimg, img2;
	public void paint(Graphics g) {
	    // Draw a background image
	    g.drawImage(bgimg, 0, 0, this);
	    // Draw the upper left 100x100 portion of another image at 10,10
	    g.drawImage(img2,
			10, 10, 110, 110,
			0, 0, 100, 100, this);
	    // Now continue drawing with original clip area
	    g.fillRect(0, 0, 10, 10);
	}
    }

イメージフリッピングを実行するための新しい API の使用方法を示すサンプルコードを、次に示します。


    import java.awt.*;
    import java.applet.*;

    public class ImgCropExample extends Applet {
    	Image img2;
	public void paint(Graphics g) {
	    // Draw the center 100x100 portion of a 200x200 image
	    // at location 10, 10, flipped horizontally.
	    g.drawImage(img2,
			10, 10, 110, 110,
			150, 50, 50, 150, this);
	}
    }


コメントの送付先: java-awt@java.sun.com
Copyright © 1996, Sun Microsystems, Inc. All rights reserved.