Swing:获取 JFrame 的图像 [英] Swing: Obtain Image of JFrame

查看:37
本文介绍了Swing:获取 JFrame 的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取 JFrame 的 java.awt.Image?

How do I obtain a java.awt.Image of a JFrame?

我想获得一个 JFrame 的屏幕截图(供以后在我的应用程序中使用).目前,这是使用机器人截取屏幕截图来完成的,指定所涉及的 JFrame 的坐标和尺寸.

I want to obtain a screen shot of a JFrame (for later use within my application). This is presently accomplished using the robot to take a screen shot specifying the coordinates and dimensions of the JFrame involved.

但是,我相信有更好的方法:Swing 组件默认情况下,在将自身绘制到屏幕上之前,将自身作为图像呈现到双缓冲区中.

However, I believe that there is a better way: Swing components, by default, render themselves as images into a double buffer prior to painting themselves onto the screen.

有没有办法从组件中获取这些图像?

Is there a way to obtain these images from the component?

推荐答案

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);
  }
} 

屏幕截图

上面显示的代码假定组件在渲染之前已在屏幕上实现.

The code shown above presumes the component has been realized on-screen, prior to rendering.

Rob Camick 展示了如何在屏幕图像 类.

Rob Camick shows how to paint an unrealized component in the Screen Image class.

另一个可能相关的主题是 在没有第一次显示的情况下渲染 JLabel,尤其是 Darryl Burke 的一行修复".

Another thread that might be of relevance, is Render JLabel without 1st displaying, particularly the 'one line fix' by Darryl Burke.

这是第二个链接中显示的代码的更新变体.

Here is an updated variant of the code shown on the second link.

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 = "<html><body style='width: 200px; padding: 5px;'>"
                + "<h1>Do U C Me?</h1>"
                + "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);
            }
        });
    }
}

屏幕截图

这篇关于Swing:获取 JFrame 的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆