java.awt.BasicStroke を使うと図形を描画するときの輪郭線をいろいろと変更できる。

BasicStroke のコンストラクタで指定できる4つの引数。

・width - BasicStroke の幅
・cap - BasicStroke の両端の装飾
・join - 輪郭線セグメントの接合部の装飾
・miterlimit - 接合トリミングの制限値

このうち、cap と join は BasicStroke が定数として持っている値を指定することになっている。
APIドキュメントでは文章で説明されているが、それではわかりにくいのでサンプル画像をここに作っておく。

以下、CAP_SQUARE, CAP_BUTT, CAP_ROUND, JOIN_MITER, JOIN_BEVEL, JOIN_ROUND の比較画像と比較画像出力用ソースコード。

まずは、CAP/JOIN の比較画像。

20070207_bssample.png

次に、比較画像出力用ソースコード。


import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
 
public class BasicStrokeSample {
 
  public static void main(String[] args) throws Exception {
    
    Polygon s1 = new Polygon();
    s1.addPoint(unit(1), unit(1));
    s1.addPoint(unit(8), unit(3));
    s1.addPoint(unit(9), unit(9));
    s1.addPoint(unit(7), unit(9));
    s1.addPoint(unit(7), unit(6));
    s1.addPoint(unit(5), unit(6));
    s1.addPoint(unit(3), unit(4));
    s1.addPoint(unit(4), unit(9));
    s1.addPoint(unit(1), unit(1));
    s1.addPoint(unit(8), unit(3));
    
    Line2D s2 = new Line2D.Double(
      unit(1), unit(9), unit(5), unit(5));
 
    Shape[] shapes = new Shape[]{s1, s2};
    
    ArrayList images = new ArrayList(); 
    
    //width - BasicStroke の幅
    //cap - BasicStroke の両端の装飾
    //join - 輪郭線セグメントの接合部の装飾
    //miterlimit - 接合トリミングの制限値
    {
      float width = 1.0f;
      int cap = BasicStroke.CAP_SQUARE;
      int join = BasicStroke.JOIN_MITER;
      float miterlimit = 10.0f;
      String[] text = {
        "width=" + width,
        "CAP_SQUARE",
        "JOIN_MITER",
        "miterlimit=" + miterlimit};
      images.add(create(width, cap, join, miterlimit, text, shapes, SIZE));
    }
    {
      float width = 12.0f;
      int cap = BasicStroke.CAP_SQUARE;
      int join = BasicStroke.JOIN_MITER;
      float miterlimit = 10.0f;
      String[] text = {
        "width=" + width,
        "CAP_SQUARE",
        "JOIN_MITER",
        "miterlimit=" + miterlimit};
      images.add(create(width, cap, join, miterlimit, text, shapes, SIZE));
    }
    {
      float width = 12.0f;
      int cap = BasicStroke.CAP_BUTT;
      int join = BasicStroke.JOIN_BEVEL;
      float miterlimit = 10.0f;
      String[] text = {
        "width=" + width,
        "CAP_BUTT",
        "JOIN_BEVEL",
        "miterlimit=" + miterlimit};
      images.add(create(width, cap, join, miterlimit, text, shapes, SIZE));
    }
    {
      float width = 12.0f;
      int cap = BasicStroke.CAP_ROUND;
      int join = BasicStroke.JOIN_ROUND;
      float miterlimit = 10.0f;
      String[] text = {
        "width=" + width,
        "CAP_ROUND",
        "JOIN_ROUND",
        "miterlimit=" + miterlimit};
      images.add(create(width, cap, join, miterlimit, text, shapes, SIZE));
    }
    
    BufferedImage image =
      new BufferedImage(
        SIZE, SIZE * images.size(),
        BufferedImage.TYPE_INT_RGB);
    Graphics2D g = image.createGraphics();
    
    for(int i=0; i<images.size(); i++){
      g.drawImage((Image)images.get(i), 0, SIZE * i, null);
    }
    
    ImageIO.write(image, "png", new File("bssample.png"));
  }
  
  private static final int SIZE = 200;
 
  private static int unit(double p){
    return (int)(SIZE * p / 10.0);
  }
 
  private static BufferedImage create(
    float width, int cap, int join, float miterlimit,
    String[] text,
    Shape[] shapes, int size){
    
    BufferedImage image =
      new BufferedImage(
        size, size, BufferedImage.TYPE_INT_RGB);
    
    Graphics2D g = image.createGraphics();
  
    for(int i=0; i<text.length; i++){
      g.drawString(text[i], 0, g.getFontMetrics().getHeight() * (i + 1));
    }
 
    g.setColor(
      new Color(
        Color.WHITE.getRed(),
        Color.WHITE.getGreen(),
        Color.WHITE.getBlue(),
        128));
    
    BasicStroke stroke = new BasicStroke(
      width, cap, join, miterlimit);
    g.setStroke(stroke);
    
    for(int i=0; i<shapes.length; i++){
      g.draw(shapes[i]);
    }
    
    g.dispose();
    return image;
  }
}

鋭角とか鈍角とか直角とか盛り込んでみたつもりだけど、どうだろう。

Ref. BasicStroke (Java 2 Platform SE 5.0)

tags: zlashdot Java Java

Posted by NI-Lab. (@nilab)