目次 | 前の項目 | 次の項目 | Java 2D API |
レンダリングのための Graphics2D コンテキストを構成するには、Graphics2D の設定 (set) メソッドを使って、RenderingHints、Stroke、Paint、クリッピングパス、Composite、Transform などの属性を指定します。
RenderingHints オブジェクトは、オブジェクトをレンダリングする方法に関する設定をすべてカプセル化しています。 Graphics2D コンテキストにレンダリングヒントを設定するには、RenderingHints オブジェクトを生成し、Graphics2D.setRenderingHints にそれを渡します。レンダリングモードの変更をサポートしていないプラットフォームもあるので、レンダリングヒントを設定しても、特定のレンダリングアルゴリズムの使用が保証されるわけではありません。
次の例では、アンチエイリアスを有効にし、レンダリングのプリファレンスを quality に設定しています。
qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHints(qualityHints);
BasicStroke では、Shape の境界線に適用される特性が定義されています。 これには、線の幅と破線パターン、線のセグメントの接続方法、および線端に適用される形状が含まれます。 Graphics2D コンテキストにストローク属性を設定するには、BasicStroke オブジェクトを生成し、それを setStroke メソッドに渡します。
ストロークの幅を設定するには、目的の幅を指定して BasicStroke オブジェクトを生成し、setStroke メソッドを呼び出します。次の例では、ストロークの幅は 12 ポイントに設定し、接続と線端の形状にはデフォルトの設定を使っています。
wideStroke = new BasicStroke(12.0f); g2.setStroke(wideStroke);
接続スタイルと線端スタイルを設定するには、目的の属性を指定して BasicStroke オブジェクトを生成します。次の例では、ストロークの幅は 12 ポイントに設定し、接続部と線端の形状には、デフォルトの設定ではなく、丸みを付けたスタイルを指定しています。
roundStroke = new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2.setStroke(roundStroke);
BasicStroke オブジェクトでは、複雑な破線パターンを簡単に定義できます。 そのためには、BasicStroke オブジェクトを作るときに、破線パターンを制御する 2 つのパラメータを指定します。
次の例では、2 種類の破線パターンが線に適用されています。 第 1 のパターンでは、ダッシュのサイズとダッシュ間の空白部のサイズは一定です。 第 2 の破線パターンはさらに複雑で、6 つの要素を持つ配列を使って、破線パターンが定義されています。
float dash1[] = {10.0f}; BasicStroke bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f); g2.setStroke(bs); Line2D line = new Line2D.Float(20.0f, 10.0f, 100.0f, 10.0f); g2.draw(line); float[] dash2 = {6.0f, 4.0f, 2.0f, 4.0f, 2.0f, 4.0f}; bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash2, 0.0f); g2.setStroke(bs); g2.draw(line);
どちらの破線パターンも破線のオフセットは 0 で、破線の描画は破線パターンの先頭から始まっています。 この 2 種類の破線パターンを図 2-7 に示します。
Graphics2D コンテキストの Paint 属性により、テキストと Shape のレンダリング時に使われる塗りつぶしの色とパターンが決まります。
GradientPaint クラスは、ある色から別の色へのグラデーションで図形を塗りつぶす簡単な方法を提供しています。 GradientPaint を作るときに、開始の位置と色および終了の位置と色を指定します。 塗りつぶしの色は、2 つの位置を結ぶ線に沿って、1 つの色から別の色まで、一定の比率で段階的に変化します。図 2-8 は、グラデーションを使った塗りつぶしの例です。
図 2-8 の第 3 の星型では、開始位置と終了位置が両方とも図形の内部にあります。 グラデーションの向きを示す線を P1 より先に延長した部分にある点は、すべて開始位置の色で描画されて、グラデーション線を P2 より先に延長した部分にある点は、すべて終了位置の色で描画されます。ある色から別の色へのグラデーションで図形を塗りつぶす場合は、次の手順で行います。
次の例では、青と緑のグラデーションで矩形を塗りつぶしています。
GradientPaint gp = new GradientPaint(50.0f, 50.0f, Color.blue 50.0f, 250.0f, Color.green); g2.setPaint(gp); g2.fillRect(50, 50, 200, 200);
TexturePaint クラスでは、繰り返しパターンで図形を塗りつぶす簡単な方法が提供されています。 TexturePaint を作るときは、パターンとして使う BufferedImage を指定します。 コンストラクタには、パターンの繰り返し単位を定義する矩形も渡します。 図 2-9 はこの塗りつぶしの例です。
テクスチャーによる図形の塗りつぶしは、次の手順で行います。
次の例では、バッファリングされたイメージから作られた簡単なテクスチャーで、矩形を塗りつぶしています。
// Create a buffered image texture patch of size 5x5 BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); // Render into the BufferedImage graphics to create the texture big.setColor(Color.green); big.fillRect(0,0,5,5); big.setColor(Color.lightGray); big.fillOval(0,0,5,5); // Create a texture paint from the buffered image Rectangle r = new Rectangle(0,0,5,5); TexturePaint tp = new TexturePaint(bi,r,TexturePaint.NEAREST_NEIGHBOR); // Add the texture paint to the graphics context. g2.setPaint(tp); // Create and render a rectangle filled with the texture. g2.fillRect(0,0,200,200);
クリッピングパスの定義は、次の手順で行います。
クリッピングパスの縮小は、次の手順で行います。
次の例では、まず楕円形でクリッピングパスを作成し、次に clip を呼び出してクリッピングパスを変更しています。
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // The width and height of the canvas int w = getSize().width; int h = getSize().height; // Create an ellipse and use it as the clipping path Ellipse2D e = new Ellipse2D.Float(w/4.0f,h/4.0f, w/2.0f,h/2.0f); g2.setClip(e); // Fill the canvas. Only the area within the clip is rendered g2.setColor(Color.cyan); g2.fillRect(0,0,w,h); // Change the clipping path, setting it to the intersection of // the current clip and a new rectangle. Rectangle r = new Rectangle(w/4+10,h/4+10,w/2-20,h/2-20); g2.clip(r); // Fill the canvas. Only the area within the new clip // is rendered g2.setColor(Color.magenta); g2.fillRect(0,0,w,h); }
Shape、テキスト文字列、または Image を変換するには、レンダリングする前に、Graphics2D コンテキストの変換パイプラインに新しい AffineTransform を追加します。 グラフィックオブジェクトをレンダリングすると、変換が適用されます。たとえば、次は、矩形を 45 度回転させて描画する手順です。
- 変換を実行する前に、現在の Graphics2D 変換を取得する。 変換をグラフィックスコンテキストに追加する前に、Graphics2D に対して getTransform を常に呼び出す (グラフィックスコンテキストが、Swing コンポーネントのレンダリングなど、他の操作に必要な変換を保持する場合があるため)
- AffineTransform.getRotateInstance を呼び出し、回転変換を取得する
- Graphics2D.transform を呼び出し、変換パイプラインに新しい変換を追加する。 setTransform を実行すると、グラフィックスコンテキスト内の現在の変換が上書きされてしまうため、新しい座標変換を追加するのに setTransform は使用しない
- Rectangle2D.Float オブジェクトを生成する
- Graphics2D.draw を呼び出し、矩形をレンダリングする
- 変換した矩形の描画後に、元の変換を使って setTransform を呼び出すことにより、Graphics2D の変換をステップ 1 で保存した元の変換に戻す
次の例では、矩形をレンダリングするときに、AffineTransform のインスタンスを使って矩形を 45 度回転させています。
AffineTransform aT = g2.getTransform(); Rectangle2D rect = new Rectangle2D.Float(1.0,1.0,2.0,3.0); AffineTransform rotate45 = AffineTransform.getRotateInstance(Math.PI/4.0,0.0,0.0); g2.transform(rotate45); g2.draw(rect); g2.setTransform(aT);
次の例では、AffineTransform を使って、中心点を軸にテキスト文字列を回転させています。
// Define the rendering transform AffineTransform at = new AffineTransform(); // Apply a translation transform to make room for the // rotated text. at.setToTranslation(400.0, 400.0); g2.transform(at); // Create a rotation transform to rotate the text at.setToRotation(Math.PI / 2.0); // Render four copies of the string "Java" at 90 degree angles for (int i = 0; i < 4; i++) { g2.drawString("Java", 0.0f, 0.0f); g2.transform(at); }
イメージも同じ方法で変換できます。 レンダリングされるグラフィックオブジェクトの種類に関係なく、レンダリングの際には Graphics2D コンテキストの変換が適用されます。Graphics2D コンテキストで定義されている変換を変更しないで、イメージに変換を適用するには、drawImage メソッドに AffineTransform を渡します。
AffineTransform rotate45 = AffineTransform.getRotateInstance(Math.PI/4.0,0.0,0.0); g2.drawImage(myImage, rotate45);
Font に変換を適用して、見た目の異なる Font を作ることもできます。 詳細については、「フォント派生の作成」を参照してください。
AlphaComposite は、あるオブジェクトが別のオブジェクトと重なるときの色のレンダリング方法を決める、合成規則をカプセル化しています。 Graphics2D コンテキストに合成スタイルを指定するには、AlphaComposite を作成し、それを setComposite メソッドに渡します。 もっとも一般的に使われる合成スタイルは SRC_OVER です。
SRC_OVER の合成規則は、デスティネーションピクセルの上にソースピクセルを合成するもので、共有されるピクセルはソースピクセルの色になります。 たとえば、青い矩形をレンダリングしてから、それと一部が重なる赤い矩形をレンダリングした場合、重なり合う部分の色は赤になります。 つまり、最後にレンダリングされたオブジェクトが、いちばん上に表示されます。
合成オブジェクトがいったん設定されると、重なりを持つオブジェクトは指定されている重ね合わせ規則に従ってレンダリングされます。
- 規則に SRC_OVER を指定して getInstance メソッドを呼び出し、AlphaComposite オブジェクトを生成する
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);- setComposite メソッドを呼び出し、Graphics2D コンテキストに AlphaComposite オブジェクトを追加する
g2.setComposite(ac);
AlphaComposite を使うと、アルファ値の定数を追加して指定できます。 この値は、ソースピクセルのアルファ値に掛けられて、ソースピクセルの透明度が高くなります。たとえば、50% の透過率でソースオブジェクトをレンダリングする AlphaComposite オブジェクトを作るには、アルファに .5 を指定します。
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);
次の例では、ソースを上に重ねるアルファ合成オブジェクトをアルファ値 .5 で作成し、グラフィックスコンテキストに追加しています。その結果、それ以降の図形は 50% の透明度でレンダリングされます。
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.red); g2.translate(100,50); // radians=degree * pie / 180 g2.rotate((45*java.lang.Math.PI)/180); g2.fillRect(0,0,100,100); g2.setTransform(new AffineTransform()); // set to identity // Create a new alpha composite AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f); g2.setComposite(ac); g2.setColor(Color.green); g2.fillRect(50,0,100,100); g2.setColor(Color.blue); g2.fillRect(125,75,100,100); g2.setColor(Color.yellow); g2.fillRect(50,125,100,100); g2.setColor(Color.pink); g2.fillRect(-25,75,100,100); }