2012-02-13 9 views
1

JPanelを拡張するコンポーネントがあります。これは、paintComponentメソッドの呼び出しごとにbufferedimageとして保存します。コンポーネントは完全に透明ではなく、バックグラウンドのみです。問題は背景が透明でないことです。私はsetOpaque(false)を使用しています。BufferedImageの背景が透明なコンポーネントですか?

これは私の関連するコードです。

private BufferedImage bufImage = null; 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Graphics2D g2 = (Graphics2D)g; 

    // if first time call 
    if (bufImage == null) { 
     int w = this.getWidth(); 
     int h = this.getHeight(); 
     bufImage = (BufferedImage)this.createImage(w, h); 
    } 

    g2.drawImage(bufImage, null, 0, 0); 

    // draw sth 
    g2.draw(sth); 
} 

-

私はそれを行うとき、私はまた

bufImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 

代わりの

bufImage = (BufferedImage)this.createImage(w, h); 

を試してみました。背景のtransperancy作品が、私は白い色で描画することができます。何が原因なのか分かりません。

注: 私はそれが動作しているかどうかを確認するためにそのコードを使用しました。

File outputfile = new File("saved.png"); 
ImageIO.write(bufImage, "png", outputfile); 

saved.pngは背景が透明ですが、図は白だけです。


これはコンポーネントであり、マウスで描画矩形のみを可能にします。

class PaintPanel extends JPanel implements MouseListener, MouseMotionListener { 
    private BufferedImage _bufImage = null; 
    private boolean dragging = false; 
    private Point _start = null, _end = null; 

    public PaintPanel() { 
     setOpaque(false); 
     this.addMouseListener(this); 
     this.addMouseMotionListener(this); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D)g; 

     if (_bufImage == null) { 
      int w = this.getWidth(); 
      int h = this.getHeight(); 
      _bufImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 
      //_bufImage = (BufferedImage)this.createImage(w, h); 
     } 

     g2.drawImage(_bufImage, null, 0, 0); 

     if (dragging) { 
      drawCurrentShape(g2); 
     } 
    } 

    private void drawCurrentShape(Graphics2D g2) { 
     int startx = (int) _start.getX(); 
     int starty = (int) _start.getY(); 
     int stopx = (int) _end.getX(); 
     int stopy = (int) _end.getY(); 

     int width = Math.abs(startx - stopx); 
     int height = Math.abs(starty - stopy); 
     int x = startx, y = starty; 
     if(x > stopx) 
      x = stopx; 
     if(y > stopy) 
      y = stopy; 

     Rectangle r = new Rectangle(x, y, width, height); 
     g2.draw(r); 
    } 

    public void mousePressed(MouseEvent e) { 
     dragging = true;  
     _start = e.getPoint(); 
     _end = _start; 
    } 

    public void mouseDragged(MouseEvent e) { 
     _end = e.getPoint(); 
     this.repaint(); 
    } 

    public void mouseReleased(MouseEvent e) { 
     _end = e.getPoint(); 
     if (dragging) { 
      dragging = false; 
      drawCurrentShape(_bufImage.createGraphics()); 
      this.repaint(); 
     } 
    } 

    public void mouseMoved (MouseEvent e) {} 
    public void mouseEntered(MouseEvent e) {} 
    public void mouseExited (MouseEvent e) {} 
    public void mouseClicked(MouseEvent e) {} 
} 
+0

私は、BufferedImageを作成すると自動的に透明になるとは思わない。 'fillRect(...)'メソッドを使って背景を透明色でペイントする必要があります。あなたのSSCCEを投稿するには、より多くの助けが必要です。 – camickr

+0

2つの場合は、print()を使用して画像を作成し、paintComponent内に画像を作成しないでください。 printはpaint()とほぼ同じですが、いくつかのフラグをオン/オフします。したがって、ペイントを使用する - >は動作しません。 paintComponent - >の中での印刷の使用は、あなたがすでに印刷フラグの設定を妨げるpaintメソッドの中にいるので動作しません。下の私の答えを見てください。 –

+0

私はあなたの答えを見ましたが、私の方法が間違っている理由を理解できませんでした。それは今働いていますが、これが将来どのような問題を引き起こす可能性がありますか?私はこのプロジェクトをベースとして使いました。 http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html。ユーザーに描画させるため、私はすべての移動の後に再描画し、それを保存しなければなりません。私はこれが良い方法だと思った。あなたが言った状況の下で私はどうすればいいですか? –

答えて

2

この試してみてください。

編集)(キーをプリントを使用することです

bufImage = new BufferedImage(w,h,java.awt.image.BufferedImage.TYPE_INT_ARGB); 
Graphics2D graphics = bufImage.createGraphics(); 
this.print(graphics); 
graphics.dispose(); 

を:私は、次を試してみましたが、透明性が魔法のように動作:

import java.awt.Dimension; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class Test2 { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final JPanel p = new JPanel(); 
     p.setPreferredSize(new Dimension(400, 400)); 
     p.setOpaque(false); 
     JButton button = new JButton("Hello world"); 
     p.add(button); 
     frame.add(p); 
     frame.pack(); 
     frame.setVisible(true); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       BufferedImage bufImage = new BufferedImage(p.getWidth(), p.getHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB); 
       Graphics2D graphics = bufImage.createGraphics(); 
       p.print(graphics); 
       graphics.dispose(); 
       try { 
        ImageIO.write(bufImage, "png", new File("d:/tmp/tmp.png")); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
+0

何も変更されていませんか?私はSSCCEを1分で投稿します。 –

+0

また、もう一つは、塗りつぶし中にすべての種類のフラグがオンとオフになっているため、paintComponent(SwingUtilities.invokeLater()を使用して)の外部で操作を実行します。 –

+0

g2.setColor(this.getForeground());を追加するだけです。私のdrawCurrentShapeメソッド。私はとにかくそれが必要になります。透明は大丈夫ですし、私は色を選ぶことができます。手伝ってくれてありがとう。 –

1

createImage(w, h)指定された幅と高さの「空白」画像が作成されます。つまり、BufferedImageインスタンスでcreateGraphicsを呼び出し、返されたGraphicsオブジェクトに直接描画する必要があります。