ここまではアプリケーションが扱う対象のデータはテキストばかりでした。しかし、特にデータを出力するという局面で、一目見て直感的に訴えることができるのはビジュアルな画像データです。もちろん、テキストのデータとしての厳密性を前提としてではありますが、ほどよく視覚的な効果を織り交ぜることで、サイトにもアクセントをつけ、より見栄えの良い「見せ方」ができるはずです。
ここでは、そのイメージデータをアプリケーションから動的に作成する方法を見てみることにします。もちろん、静的なイメージデータをその都度用意するのも悪くはありません。しかし、データベースのデータなどを基にして、日々変動する値をグラフ化したい場合などはやはり静的なデータよりも動的にデータを生成した方がリアルタイムに状況を把握できますし、何よりも「楽」です。
リスト4は、アプリケーションから単純な画像を生成する一例です。次回に予定しているデータベース接続の記事とも併せて読むことで、日々の業務データをグラフ表示するなどにも応用できるはずです。
<%@ page contentType="image/jpeg; charset=Shift_JIS" import="java.awt.*,java.awt.image.*,com.sun.image.codec.jpeg.*" %> <% BufferedImage objBi=new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB); Graphics objGrh=objBi.getGraphics(); objGrh.setColor(new Color(255,255,255)); objGrh.fillRect(0,0,200,200); objGrh.setFont(new Font("HG丸ゴシックM-PRO",Font.BOLD,11)); objGrh.setColor(new Color(0,0,255)); objGrh.drawString("http://www.wings.msn.to/",10,180); objGrh.setColor(new Color(230,230,180)); objGrh.fillRect(10,10,100,100); objGrh.drawOval(5,5,180,180); JPEGImageEncoder objEnc=JPEGCodec.createJPEGEncoder(response.getOutputStream()); objEnc.encode(objBi); %>
リスト4の実行結果は以下のとおりです。
リスト4の内容を説明しましょう。BufferedImageクラスの役割とは、いわゆるメモリ空間のキャンバスを提供することにあります。インスタンス(オブジェクト)の生成に際しては、画像の高さ、幅、そして形式を指定します。
Graphicsクラスは、このメモリ上のキャンバスに対して、実際に描画を行う絵筆であり、絵の具だと思っておけばよいでしょう。Graphicsクラスには画像を描くためのさまざまな道具が存在しますが、さほど難しいことはありません。絵筆を取り替え、絵の具を変え、また、描画する形が変わるだけで、パラメータの内容も直感的に理解できるはずです。以下では、Graphicsクラスの主なメソッドを挙げておきますので、詳細はAPIリファレンスなどを参照し、自分で実際にいろいろと試してみるのも面白いかもしれません。
メソッド | 概要 |
---|---|
draw3DRect(int x,int y,int width,int height,boolean raised) | 3Dで強調された矩形を描画 |
drawArc(int x,int y,int width,int height,int startAngle,int arcAngle) | 指定された矩形を包含するだ円弧を描画 |
drawLine(int x1,int y1,int x2,int y2) | (x1,y1)-(x2,y2)の直線を描画 |
drawOval(int x,int y,int width,int height) | だ円を描画 |
drawPolygon(int[] xPoints,int[] yPoints,int nPoints) | 指定された座標を頂点とした多角形を描画(nPointは頂点の数) |
drawPolyline(int[] xPoints,int[] yPoints,int nPoints) | 指定された座標を結ぶ連続線を描画 |
drawRect(int x,int y,int width,int height) | 矩形を描画 |
void drawRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight) | 角が丸い矩形を描画 |
drawString(String str,int x,int y) | 文字列を描画 |
fill3DRect(int x,int y,int width,int height,boolean raised) | 3Dで強調された塗り潰し矩形を描画 |
fillArc(int x,int y,int width,int height,int startAngle,int arcAngle) | 指定された矩形を包含する塗り潰しだ円弧を描画 |
fillOval(int x,int y,int width,int height) | 塗り潰し楕円を描画 |
fillPolygon(int[] xPoints, int[] yPoints, int nPoints | 指定された座標を頂点とした塗り潰し多角形を描画(nPointは頂点の数) |
fillRect(int x, int y, int width, int height) | 塗り潰し矩形を描画 |
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) | 角が丸い塗り潰し矩形を描画 |
setColor(Color c) | 描画色を指定 |
setFont(Font font) | 描画フォントを指定 |
BufferedImage上に描画されたイメージは、JPEGImageEncoderクラスによってJPEG形式にエンコードされたうえでクライアントサイドに出力されます。JPEGImageEncoderオブジェクトは、JPEGCodec.createJPEGEncoderメソッドを介して取得することができます。引数として、出力先を指定する点に注目してください。ここではHttpServletResponse#getOutputStreamメソッドが返すServletOutputStreamオブジェクトを出力先とします。
ServletOutputStreamは、バイナリデータをクライアントに出力する際に使用するオブジェクトです。出力に際して、データに余計なエンコードなどを行いません。
最終的に、エンコード処理を行うのは、JPEGImageEncoder#encodeメソッドです。encodeメソッド自体は戻り値を返さず、エンコード結果は上で指定されたServletOutputStreamオブジェクトに引き渡されます。
メモリ上に画像を保持するのはBufferedImageクラスの役割です。GraphicsオブジェクトはBufferedImageに対して、さまざまな加工処理を行います。最終的に生成された画像データを出力するには、JPEGImageEncoderクラスでエンコード処理を行う必要があります。
以上、いかがだったでしょうか。第7回、第8回と併せて、自分のやりたいことを実現するためのさまざまな手法がイメージできてきたでしょうか。ここで扱うのは、あくまで断片的な知識ですが、皆さんはこの後、現実のサイトで実際にこれらのTIPSを活用してみてください。最初は、ちょっとした引数の変更などでも、構わないはずです。とにかく具体的なアプリケーションへの組み込みの過程で、ここで学んだ断片的な知識が総合的なノウハウとして、きっと昇華されるはずです。本稿がその1つのきっかけとなれば幸いです。
Copyright © ITmedia, Inc. All Rights Reserved.