2012-06-19 15 views
5

私はJPanelにペイントするプログラムを書いています。どのようにそれに塗られているJPanelImageを取得するのですか? 私はこのコードを試しましたが、私が得るのは背景色が私のJPanelの空白の画像です。 BufferedImageには、自分のパネルにペイントされているものは含まれていません。Java - JPanelの画像を取得

private BufferedImage createImage(JPanel panel) {  
     int w = panel.getWidth(); 
     int h = panel.getHeight(); 
     BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
     Graphics2D g = bi.createGraphics(); 
     panel.paint(g); 
     return bi; 
    } 

私は間違っていますか?

+0

は、あなたのイメージを描く方法を掲示することを検討してください。 graphics.drawImageを使用していますか?はいの場合、ImageObserver引数は何ですか? –

答えて

2

ここには、動作することを示すSSCCEがあります。よくある間違いはをdrawImageメソッドのImageObserverとして渡すことです。画像のロードは非同期であるためです。

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class TestPrint { 

    protected static void initUI() throws MalformedURLException { 
     final ImageIcon image = new ImageIcon(new URL("http://www.travelblog.org/Wallpaper/pix/tb_fiji_sunset_wallpaper.jpg")); 
     JPanel panel = new JPanel() { 
      @Override 
      protected void paintComponent(java.awt.Graphics g) { 
       super.paintComponent(g); 
       g.drawImage(image.getImage(), 0, 0, this); 
      }; 
     }; 
     panel.setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight())); 
     panel.setSize(panel.getPreferredSize()); 
     BufferedImage bi = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB); 
     Graphics g = bi.createGraphics(); 
     panel.print(g); 
     g.dispose(); 
     try { 
      ImageIO.write(bi, "png", new File("test.png")); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        initUI(); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
+0

それを試して、doesnt仕事。 –

+2

@sijoune上記のコードを試してみて、問題を特定するコードとの相違点を確認してください。 –

2

あなたのコードは私に適しています。

ここは簡単な例です。フレームのサイズを変更すると、パネルのサイズが変わり、画像が移動します。

public static void main(String[] args) { 
    JFrame frame = new JFrame("Test"); 
    JPanel panel = new JPanel(); 
    panel.setBackground(Color.BLUE); 
    JLabel label = new JLabel("Image"); 
    label.setForeground(Color.RED); 
    panel.add(label); 
    frame.add(panel, BorderLayout.NORTH); 
    frame.pack(); 
    JLabel image = new JLabel(new ImageIcon(createImage(panel))); 
    frame.add(image, BorderLayout.SOUTH); 
    frame.pack(); 
    label.setText("Original");  
    frame.setVisible(true); 
} 

private static BufferedImage createImage(JPanel panel) { 
    int w = panel.getWidth(); 
    int h = panel.getHeight(); 
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g = bi.createGraphics(); 
    panel.paint(g); 
    return bi; 
} 

問題は他の場所にある必要があります。パネルの画像を作成する時点でパネルのサイズが正になっていることを確認してください。

2

ここでは、Java 2/JDK 1.2アプリケーションのいずれかに追加できる簡単な方法を示します。スナップショットを作成するコンポーネントと保存するファイル名を渡すだけです。

public void saveComponentAsJPEG(Component myComponent, String filename) { 
    Dimension size = myComponent.getSize(); 
    BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2 = myImage.createGraphics(); 
    myComponent.paint(g2); 
    try { 
     OutputStream out = new FileOutputStream(filename); 
     JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
     encoder.encode(myImage); 
     out.close(); 
    } catch (Exception e) { 
     System.out.println(e); 
    } 
} 

この方法は非常に汎用性があります。これは、さまざまなJavaアプリケーションコンポーネントのスナップショットを取得するために使用できます。ただし、コードの移植性にリスクがある場合は、com.sun.image.codec.jpegを使用することをお勧めします。

EDIT: 私が確認するために、コードをテストし、すべての罰金だ:

import com.sun.image.codec.jpeg.JPEGCodec; 
import com.sun.image.codec.jpeg.JPEGImageEncoder; 
import java.awt.*; 
import java.awt.geom.Ellipse2D; 
import java.awt.image.BufferedImage; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ScreenCapture extends JFrame { 

    public ScreenCapture() { 
     createAndShowUI(); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ScreenCapture screenCapture = new ScreenCapture(); 
      } 
     }); 
    } 

    private void createAndShowUI() { 
     setTitle("Test Screen Capture"); 
     setSize(300, 300); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
     getContentPane().add(new DrawingPanel()); 
     setVisible(true); 
     saveComponentAsJPEG(this, "C:/test.jpg"); 

    } 

    public void saveComponentAsJPEG(Component myComponent, String filename) { 
     Dimension size = myComponent.getSize(); 
     BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB); 
     Graphics2D g2 = myImage.createGraphics(); 
     myComponent.paint(g2); 
     try { 
      OutputStream out = new FileOutputStream(filename); 
      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
      encoder.encode(myImage); 
      out.close(); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

    class DrawingPanel extends JPanel { 

     public DrawingPanel() { 
      setDoubleBuffered(true); 
     } 

     @Override 
     public void paintComponent(Graphics grphcs) { 
      super.paintComponents(grphcs); 
      Graphics2D g2d = (Graphics2D) grphcs; 

      RenderingHints rhints = g2d.getRenderingHints(); 
      boolean antialiasOn = rhints.containsValue(RenderingHints.VALUE_ANTIALIAS_ON); 

      if (!antialiasOn) { 
       g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      } 

      Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f); 

      g2d.setColor(Color.RED); 
      g2d.draw(circle); 
      g2d.fill(circle); 
     } 
    } 
} 
+0

私はそれを試して、同じことが起こります。理解できません。私は何か間違ったことをする必要がありますが、私はそれを見つけることができません。 –

+0

私の編集をチェックして、問題を起こしている可能性のあるコードを投稿すると、一度はコンポーネントとファイル名をメソッドに渡して残りの部分を渡すことができますので、 –

関連する問題