如何捕获屏幕到图像,在GUI的组件上绘制并在某些区域绘制框?

时间:2011-12-16 09:54:38

标签: java swing user-interface drawing awt

我正在使用以下示例拍摄屏幕截图:

try {
   Robot robot = new Robot();
   BufferedImage image = robot.createScreenCapture(new Rectangle(0, 0, 200, 200));
} catch java.awt.AWTException exc) {
    System.out.println("error: main");
}

现在我想在GUI的一个组件上绘制屏幕截图。我不知道应该使用哪个组件,但我想每帧绘制图像(需要大约20 FPS),它看起来像电影,照相机拍摄我的桌面。并且,我想在绘制区域的某些区域绘制框。

我怎么能这样做?我所展示的每个例子都遵循:

  • 在程序启动时从文件系统加载图像 吸引到JPanel,因此我不能轻易地在它上画画 我想这样做。

这不起作用(灰色面板):

visualization = new JPanel();
visualization.setLayout(new BorderLayout());
try {
        Robot robot = new Robot();
        BufferedImage image = robot.createScreenCapture(new Rectangle(0, 0, 200, 200));
        Graphics2D g = image.createGraphics();
        visualization.paint(g);
        visualization.setVisible(true);

    }
    catch(java.awt.AWTException exc) {
        System.out.println("error: main");
    }

3 个答案:

答案 0 :(得分:2)

据我所知,最佳方式是将图片Icon添加到JLabel,简单示例

import javax.imageio.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;

public class CaptureScreen implements ActionListener {

    private JFrame f = new JFrame("Screen Capture");
    private JPanel pane = new JPanel();
    private JButton capture = new JButton("Capture");
    private JDialog d = new JDialog();
    private JScrollPane scrollPane = new JScrollPane();
    private JLabel l = new JLabel();
    private Point location;

    public CaptureScreen() {
        capture.setActionCommand("CaptureScreen");
        capture.setFocusPainted(false);
        capture.addActionListener(this);
        capture.setPreferredSize(new Dimension(300, 50));
        pane.add(capture);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(pane);
        f.setLocation(100, 100);
        f.pack();
        f.setVisible(true);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createPicContainer();
            }
        });
    }

    private void createPicContainer() {
        l.setPreferredSize(new Dimension(700, 500));
        scrollPane = new JScrollPane(l,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setBackground(Color.white);
        scrollPane.getViewport().setBackground(Color.white);
        d.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        d.add(scrollPane);
        d.pack();
        d.setVisible(false);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("CaptureScreen")) {
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); // gets the screen size
            Robot r;
            BufferedImage bI;
            try {
                r = new Robot(); // creates robot not sure exactly how it works
                Thread.sleep(1000); // waits 1 second before capture
                bI = r.createScreenCapture(new Rectangle(d)); // tells robot to capture the screen
                showPic(bI);
                saveImage(bI);
            } catch (AWTException e1) {
                e1.printStackTrace();
            } catch (InterruptedException e2) {
                e2.printStackTrace();
            }
        }
    }

    private void saveImage(BufferedImage bI) {
        try {
            ImageIO.write(bI, "JPG", new File("screenShot.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void showPic(BufferedImage bI) {
        ImageIcon pic = new ImageIcon(bI);
        l.setIcon(pic);
        l.revalidate();
        l.repaint();
        d.setVisible(false);
        location = f.getLocationOnScreen();
        int x = location.x;
        int y = location.y;
        d.setLocation(x, y + f.getHeight());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                d.setVisible(true);
            }
        });
    }

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

            @Override
            public void run() {
                CaptureScreen cs = new CaptureScreen();
            }
        });
    }
}

答案 1 :(得分:1)

  

我怎么能这样做?我所展示的每个例子都遵循以下步骤:在程序启动时从文件系统加载图像并将其绘制到JPanel,因此我无法轻易地在其上绘制图像。

这是要走的路。扩展JPanel并覆盖paintComponent,为自定义绘图添加鼠标侦听器,并在BufferdImage方法中的paintComponent之上绘制图形。

<强>更新

如果您不知道如何扩展 JPanel实施 paintComponent,请参阅我对How to draw a JPanel as a Nimbus JButton?的回答

答案 2 :(得分:1)

我也建议mOorbel提到的方式,顺便说一句,如果你真的想按照你说的方式,这就是工作代码..

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ImagePane extends JPanel{

    private BufferedImage image;

    public ImagePane()  {


            try {
               Robot robot = new Robot();
                 image = robot.createScreenCapture(new Rectangle(0, 0, 500, 500));
            } catch (AWTException ex) {
                Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, null, ex);
            }

    }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null); 

    }
public static void main(String[] args) {

        JFrame test = new JFrame();

            test.add(new ImagePane());
            Dimension b = new Dimension(500,500);
            test.setMinimumSize(b);

        test.setVisible(true);

    }
}