如何获得paint / paintComponent生成的图像?

我有一个快速的问题。 如何获取JComponent.paint或paintComponent生成的图像?

我有一个JComponent,我用它作为’工作区’,我已经覆盖了paintComponent方法到我自己的方法。 问题是我的工作区JComponent也有子项,它们有自己的paintComponent方法。

因此,当Swing渲染我的工作区组件时,它会渲染工作区图形,然后渲染其子图形。

但是,我想获取我的工作区组件生成的图像(包括工作区图形和子图形)。

我怎么做?

我试图通过使用我自己的Graphics自己调用paintComponent / paint-method,但我刚刚返回了一个黑色图像。 这是我尝试过的;

public void paintComponent(Graphics g) { if (bufferedImage != null) { g.drawImage(bufferedImage, 0, 0, this); } else { g.setColor(Color.WHITE); g.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight()); } } public BufferedImage getImage() { BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics g = hello.getGraphics(); paintComponent( g ); return hello; } 

欢迎任何想法或意见! 🙂

如果过早调用getImage,您的组件将不会显示,并且仍然具有0宽度和高度。 你确定你在很晚的时候打电话吗? 尝试将组件的大小打印到标准输出并查看其尺寸。

似乎问题是由于BufferedImage的创建方式。 使用时:

 BufferedImage hello = bufferedImage.getSubimage(0,0, getWidth(), getHeight()); 

相反,它奏效了。 我还必须将paintComponent中的切换更改为绘制以渲染子项。

问题解决了,但如果有人知道的话。 为什么我的:

  BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); 

总是呈现黑色图像? Offtopic,但可能有趣的知道:)

将新的BufferedImage更改为TYPE_INT_RGB可以解决这个问题。 我不能给出一个解释 – 只是一个Swing之谜。

 public BufferedImage getImage() { BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); Graphics g = hello.getGraphics(); paintComponent( g ); return hello; } 

不要从外部调用paintComponent()或paint()。 相反,让您的图像在那些(覆盖的)方法中创建。 然后,您可以确保您的图像实际上包含组件的绘制内容。

这是一个示例应用程序。 ImagePanel实际上会在每次绘制时抓取组件的图形内容,这可能有点浪费,因此您可能需要调整完成此操作的频率。

 public class SomeApp extends JFrame { private static class ImagePanel extends JPanel { private BufferedImage currentImage; public BufferedImage getCurrentImage() { return currentImage; } @Override public void paint(Graphics g) { Rectangle tempBounds = g.getClipBounds(); currentImage = new BufferedImage(tempBounds.width, tempBounds.height, BufferedImage.TYPE_INT_ARGB); super.paint(g); super.paint(currentImage.getGraphics()); } } public SomeApp() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setSize(800,600); int matrixSize = 4; setLayout(new BorderLayout()); add(new JLabel("Wonderful Application"), BorderLayout.NORTH); final ImagePanel imgPanel = new ImagePanel(); imgPanel.setLayout(new GridLayout(matrixSize,matrixSize)); for(int i=1; i<=matrixSize*matrixSize; i++) { imgPanel.add(new JButton("A Button" + i)); } add(imgPanel, BorderLayout.CENTER); final JPanel buttonPanel = new JPanel(); buttonPanel.add(new JButton(new AbstractAction("get image") { @Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(SomeApp.this, new ImageIcon(imgPanel.getCurrentImage())); } })); add(buttonPanel, BorderLayout.SOUTH); } public static void main(String[] args) { System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new SomeApp().setVisible(true); } }); } } 

就像Martijn所说,你的图像可能是黑色的,因为该组件甚至还没有绘制/显示。 您可以添加ComponentListener以在显示时收到通知。 使用getSubimage的“解决方案”与实际问题无关。 我建议你删除它。