![]() ![]() ![]() ![]() |
グラフィックスを扱う |
次のアプレットはフィルタを使用してイメージを回転させる。 この RotateFilter という名前の特製フィルタについては次のページで説明する。 フィルタについて知っておくべきことは、そのコンストラクタが 1 個の倍精度引数をとるということだけである。この引数にはラジアン単位のローテー ション角度が指定される。 このアプレットはユーザが入力した数値を度からラジアンに変換し、アプレットが RotateFilter を作成できるようにしている。
以下に、ソースコードのフィルタを使用する部分を示す。 (プログラム全体も参照できる。)
public class ImageRotator extends Applet { . . . RotatorCanvas rotator; double radiansPerDegree = Math.PI / 180; public void init() { //イメージをロードする。 Image image = getImage(getCodeBase(), "../images/rocketship.gif"); ...//イメージフィルタを使用するコンポーネントを作成する。 rotator = new RotatorCanvas(image); . . . add(rotator); . . . } public boolean action(Event evt, Object arg) { int degrees; ...//イメージの回転角度を取り込む。 //ラジアンに変換する。 rotator.rotateImage((double)degrees * radiansPerDegree); return true; } } class RotatorCanvas extends Canvas { Image sourceImage; Image resultImage; public RotatorCanvas(Image image) { sourceImage = image; resultImage = sourceImage; } public void rotateImage(double angle) { ImageFilter filter = new RotateFilter(angle); ImageProducer producer = new FilteredImageSource( sourceImage.getSource(), filter); resultImage = createImage(producer); repaint(); } public void paint(Graphics g) { Dimension d = size(); int x = (d.width - resultImage.getWidth(this)) / 2; int y = (d.height - resultImage.getHeight(this)) / 2; g.drawImage(resultImage, x, y, this); } }コードが動作する仕組み
イメージフィルタを使用する場合、プログラムは以下のステップをたどる。
- Image オブジェクトを取り込む (通常は getImage() メソッドで 行う)。
- getSource() メソッドを使用し、Image オブジェクトのデータソ ース (ImageProducer) を取り込む。
- 必要に応じてイメージフィルタを初期化し 、フィルタのインスタンスを作成する。
- コンストラクタにイメージソースオブジェクトとフィルタオブジェクトを渡し 、FilteredImageSource オブジェクトを作成する。
- Component の createImage() メソッドで、イメージプロデュー サとして FilteeredImageSource をもつ新しい Image オブジェクトを作成する。
複雑そうに見えるかもしれないが、実際には簡単に実装できる。 本当に複雑なのは少し後で説明するとおり、内部の動きである。 まず、イメージフィルタを使用するアプレット例のコードについて解説する。
アプレット例では、RotatorCanvas の rotateImage() メソッドが、イ メージフィルタの使用に関連するタスクのほとんどを実行する。 これに当てはまらないのは、元の Image オブジェクトを取り込む第 1 ステップであ り、これはアプレットの init() メソッドによって実行される。この Image オブジェクトは RotatorCanvas に渡され、そこで sourceImage として参照される。
rotateImage() メソッドは、フィルタのコンストラクタを呼び出して イメージフィルタをインスタンス化する。 コンストラクタへの 1 個の引数は、ラジアン単位のイメージの回転角度である。
ImageFilter filter = new RotateFilter(angle);次に、rotateImage() メソッドが FilteredImageSource インスタンス を作成する。 FilteredImageSource コンストラクタへの最初の引数は getSource() メソッドを使って得られたイメージソースである。 2 番目の引数はフィルタオブジェクトである。
ImageProducer producer = new FilteredImageSource( sourceImage.getSource(), filter);最後にコードは、Component の createImage() メソッドを起動して、 resultImage という名前の別の Image を作成する。 createImage() へのただ 1 つの引数は上のステップで作成された FilteredImageSource である。
resultImage = createImage(producer);内部で起きること
このセクションでは、イメージフィルタリングが内部でどのように動作しているかに ついて解説する。 このような実装上の詳細を気にしたくない場合は、イメージフィル タの保管場所へスキップしてよい。
最初に理解しなければならないことは、AWT が drawImage() 要求に答 えて内部で ImageConsumer を使用していることである。 したがって、イメージコンシューマに該当するのはイメージを表示する Component ではなく、AWT の奥深くにある何らかのオブジェクトである。
上記の createImage() 呼び出しは、プロデューサである FilteredImageSource インスタンスからイメージデータを得ようとする Image (resultImage) を設定する。 ここで、resultImageの観点から見たイメージデータのパスを示す。
点線は、イメージコンシューマが実際には FilteredImageSource からデータを取り込まないことを表している。 その代わりに FilteredImageSource は、 イメージコンシューマが (g.drawImage(resultImage,...) に応えて) イメージデータを要求したとき、何らかの技を実行し、別の道筋をつける。以下に、 FilteredImageSource が実行する技を示す。
- ユーザが FilteredImageSource コンストラクタに指定したフィルタオブジェク トに getFilterInstance() メソッドを起動することによって新規のイ メージフィルタオブジェクトを作成する。 デフォルトでは、 getFilterInstance() がフィルタオブジェクトのクローンを作る。
- 新規のイメージフィルタオブジェクトをイメージコンシューマに接続する。
- ユーザが FilteredImageSource コンストラクタに指定したイメージデータソースをイメージフィルタに接続する。
この結果、次のようになる。
イメージフィルタの保管場所
ここでは、既存のイメージフィルタが納めてある場所について述べる。 java.AWT.image パッケージにはいつでも使える CropImageFilter
フィルタが組み込ま れている。このフィルタは、元のイメージの矩形範囲から成る イメージを作り出すものである。 ほかにも、当社の Web サイトでアプレットが使用しているイメージフィルタがいく つかある。 以下に示すページにはすべて、それぞれのアプレットとイメージフィルタのソースコ ードへのリンクが組み込まれている。
- 動的に作 成されたカラーのブレット ページには、イメージのカラーを変更する 2 つのアプレットが納められている。 1 つ目の AlphaBullet は AlphaColorFilter を定義し使用し、2 つ目の HueBullet は HueFilter を定義し使用する。
- イメー ジマップのライブなフィードバック ページはイメージマッピングのアプレット を実演する。 多数のフィルタを使用し、カーソルが特定の領域の上にきたときやユーザが特 別な領域をクリックしたときに目に見えるフィードバックを実行する。
- イメー ジのテスト ページは、さまざまなイメージ処理を実行する。 ユーザにイメージのスケーリングや移動を行わせるほか、3 つのフィルタを定義し使用している。 AlphaFilter はイメージを透明にし、RedBlueSwapFilter はイメージのカラー を変え、RotateFilter はこのセクションで見てきたようにイメージを回転させる。
![]() ![]() ![]() ![]() |
グラフィックスを扱う |