Swing: obtener la imagen de JFrame

¿Cómo java.awt.Image una java.awt.Image de un JFrame?

Quiero obtener una captura de pantalla de un JFrame (para usarlo luego en mi aplicación). Esto se logra actualmente utilizando el robot para tomar una captura de pantalla que especifica las coordenadas y dimensiones del JFrame involucrado.

Sin embargo, creo que hay una manera mejor: los componentes Swing, por defecto, se muestran como imágenes en un doble buffer antes de pintarse en la pantalla.

¿Hay alguna forma de obtener estas imágenes del componente?

ComponentImageCapture.java

 import java.awt.BorderLayout; import java.awt.Component; import java.awt.Image; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.InputEvent; import javax.swing.*; import javax.swing.border.TitledBorder; import javax.imageio.ImageIO; import java.io.File; /** Create a screenshot of a component. @author Andrew Thompson */ class ComponentImageCapture { static final String HELP = "Type Ctrl-0 to get a screenshot of the current GUI.\n" + "The screenshot will be saved to the current " + "directory as 'screenshot.png'."; public static BufferedImage getScreenShot( Component component) { BufferedImage image = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB ); // call the Component's paint method, using // the Graphics object of the image. component.paint( image.getGraphics() ); // alternately use .printAll(..) return image; } public static void main(String[] args) { Runnable r = new Runnable() { public void run() { final JFrame f = new JFrame("Test Screenshot"); JMenuItem screenshot = new JMenuItem("Screenshot"); screenshot.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_0, InputEvent.CTRL_DOWN_MASK )); screenshot.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent ae) { BufferedImage img = getScreenShot( f.getContentPane() ); JOptionPane.showMessageDialog( null, new JLabel( new ImageIcon( img.getScaledInstance( img.getWidth(null)/2, img.getHeight(null)/2, Image.SCALE_SMOOTH ) ))); try { // write the image as a PNG ImageIO.write( img, "png", new File("screenshot.png")); } catch(Exception e) { e.printStackTrace(); } } } ); JMenu menu = new JMenu("Other"); menu.add(screenshot); JMenuBar mb = new JMenuBar(); mb.add(menu); f.setJMenuBar(mb); JPanel p = new JPanel( new BorderLayout(5,5) ); p.setBorder( new TitledBorder("Main GUI") ); p.add( new JScrollPane(new JTree()), BorderLayout.WEST ); p.add( new JScrollPane( new JTextArea(HELP,10,30) ), BorderLayout.CENTER ); f.setContentPane( p ); f.pack(); f.setLocationRelativeTo(null); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }; SwingUtilities.invokeLater(r); } } 

Captura de pantalla

GUI con imagen capturada

Ver también

El código que se muestra arriba supone que el componente se realizó en la pantalla, antes de renderizar.

Rob Camick muestra cómo pintar un componente no realizado en la clase Imagen de pantalla .

Otro hilo que podría ser relevante es Render JLabel sin la 1ra visualización , especialmente la ‘corrección de una línea’ de Darryl Burke.

LabelRenderTest.java

Aquí hay una variante actualizada del código que se muestra en el segundo enlace.

 import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; public class LabelRenderTest { public static void main(String[] args) { SwingUtilities.invokeLater( new Runnable() { public void run() { String title = "" + "

Do UC Me?

" + "Here is a long string that will wrap. " + "The effect we want is a multi-line label."; JFrame f = new JFrame("Label Render Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); BufferedImage image = new BufferedImage( 400, 300, BufferedImage.TYPE_INT_RGB); Graphics2D imageGraphics = image.createGraphics(); GradientPaint gp = new GradientPaint( 20f, 20f, Color.red, 380f, 280f, Color.orange); imageGraphics.setPaint(gp); imageGraphics.fillRect(0, 0, 400, 300); JLabel textLabel = new JLabel(title); textLabel.setSize(textLabel.getPreferredSize()); Dimension d = textLabel.getPreferredSize(); BufferedImage bi = new BufferedImage( d.width, d.height, BufferedImage.TYPE_INT_ARGB); Graphics g = bi.createGraphics(); g.setColor(new Color(255, 255, 255, 128)); g.fillRoundRect( 0, 0, bi.getWidth(f), bi.getHeight(f), 15, 10); g.setColor(Color.black); textLabel.paint(g); Graphics g2 = image.getGraphics(); g2.drawImage(bi, 20, 20, f); ImageIcon ii = new ImageIcon(image); JLabel imageLabel = new JLabel(ii); f.getContentPane().add(imageLabel); f.pack(); f.setLocationByPlatform(true); f.setVisible(true); } }); } }

Captura de pantalla

Etiqueta procesada en la imagen