拡大すると円の周りのギザギザが気になります。

BufferedImageをパネルより大きくして常に縮小すれば良くなるでしょうか
パネルのコンストラクタで2倍の大きさのBufferedImageにしてみます。
public MyPanel(int width, int height){
setPreferredSize(new Dimension(width,height));
buffimg = new BufferedImage(
width*2, height*2, BufferedImage.TYPE_INT_RGB);
bfg = buffimg.createGraphics();
bfg.setColor(bgcolor);
bfg.fillRect(0, 0, width*2, height*2);
}
最後の2行は背景色を塗っている部分です。これも広くしないとなりません。
次のようになります。

この失敗は円の描画部分drawToBuff()メソッドに400,300が直に書いてあるからです。この400,300はBufferedImageの大きさの範囲という意味ですから今回は800,600にすべきです。
int x = (int)(400*Math.random()); int y = (int)(300*Math.random()); int h = (int)(50*Math.random()+5);
800,600以外にしても直さなくても良いようにbuffimg.getWidth(), buffimg.getHeight() にしておきます。
int x = (int)(buffimg.getWidth()*Math.random()); int y = (int)(buffimg.getHeight()*Math.random()); int h = (int)(buffimg.getWidth()*Math.random()/8+buffimg.getWidth()/80);
大きさも400で50の割合なら800で100にすべきです。つまりwidthの1/8とします。先に割ると切り捨てで誤差が出ますから後で割ります。最低幅の5も幅の1/80とすると同じ割合に拡大できます。
左上の数字が小さいので大きく描いて縮小していることがわかります。あまり変わっていません。

GIMPで400%に表示したもので比較します。
| パネルが400x300 | パネルを4倍に拡大 | |
| BufferedImage 1600x1200 |
![]() 400x300のパネルに1/4に縮小して表示 |
![]() 4倍(1600x1200程度)のパネルに表示(およそ等倍) |
| BufferedImage 400x300 |
![]() 400x300ののパネルに等倍表示。 |
![]() 4倍(1600x1200程度)のパネルに表示(およそ4倍) |
| 結論 | BufferedImage よりパネルが小さい時には ギザギザの大きさはどちらも1ピクセルで 良くなりません |
BufferedImage よりパネルを大きくした時に ギザギザが強調されるのを抑えることができます |
setRenderingHintを使うにはまず Graphics でなく Graphics2D クラスを使います。
public class MyPanel extends JPanel{
BufferedImage buffimg;
Graphics2D bfg;
Graphics2D クラスのインスタンスにsetRenderingHintでアンチエイリアスの設定をします。
buffimg = new BufferedImage(
width,height,BufferedImage.TYPE_INT_RGB);
bfg = buffimg.createGraphics();
bfg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
bfg.setColor(bgcolor);
bfg.fillRect(0, 0, width, height);
![]() setRenderingHint |
![]() setRenderingHint |
BufferedImage 2倍
public MyPanel(int width, int height){
setPreferredSize(new Dimension(width,height));
buffimg = new BufferedImage(
width*2,height*2,BufferedImage.TYPE_INT_RGB);
bfg = buffimg.createGraphics();
bfg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
bfg.setColor(bgcolor);
bfg.fillRect(0, 0, width*2, height*2);
![]() BufferedImage x2 |
![]() BufferedImage x2 |
BufferedImage 4倍
public MyPanel(int width, int height){
setPreferredSize(new Dimension(width,height));
int r=4;
buffimg = new BufferedImage(
width*r,height*r,BufferedImage.TYPE_INT_RGB);
bfg = buffimg.createGraphics();
bfg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
bfg.setColor(bgcolor);
bfg.fillRect(0, 0, buffimg.getWidth(), buffimg.getHeight());
}
![]() BufferedImage x4 |
![]() BufferedImage x4 |
| 0. | ![]() |
![]() |
| 1. | ![]() setRenderingHint |
![]() setRenderingHint |
| 2. | ![]() BufferedImage x2 |
![]() BufferedImage x2 |
| 3. | ![]() BufferedImage x4 |
![]() BufferedImage x4 |
上記プログラムをつくって動作を確認しなさい。
setRenderingHintが使えるのは線や楕円などの図形を描くときであって、 drawImage()メソッドで次のようにしても効果がない。
public void paintComponent(Graphics g){
Graphics2D myg = (Graphics2D)g;
pcct++;
myg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int pnlw = getSize().width;
int imgh = buffimg.getHeight() * pnlw / buffimg.getWidth();
myg.drawImage(buffimg, 0, 0, pnlw, imgh, this);
![]() BIx4 |
![]() BIx4 |
![]() BIx4 |
![]() BIx4 |