Search code examples
javaimageswingjlabel

Capturing and displaying an image using Java


I want to create an app which captures the screen (1280x720 res) and then displays it. The code for this is in a while loop so it's ongoing. Here's what I have:

import javax.swing.*;

import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;

public class SV1 {

    public static void main(String[] args) throws Exception {
        JFrame theGUI = new JFrame();
        theGUI.setTitle("TestApp");
        theGUI.setSize(1280, 720);
        theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        theGUI.setVisible(true);

        Robot robot = new Robot();

        while (true) {
            BufferedImage screenShot = robot.createScreenCapture(new Rectangle(1280,720));

            JLabel picLabel = new JLabel(new ImageIcon( screenShot ));
            theGUI.add(picLabel);
        }
    }
}

I figured this out from this answer but it isn't ideal for what I want. First of all, for some reason I'm not sure of, it causes java to run out of memory "Java heap space". And secondly it doesn't work properly as the image shown isn't updated.

I've read about using Graphics (java.awt.Graphics) to draw the image. Can anyone show me an example of this? Or perhaps point me in the right direction if there's a better way?


Solution

  • it causes java to run out of memory "Java heap space"

    You are looping forever and continuosly adding new JLabels to your JFrame. You could try instead of recreating each time the JLabel, to simply set a new ImageIcon:

    JLabel picLabel = new JLabel();
    theGUI.add(picLabel);
    while (true) 
    {
        BufferedImage screenShot = robot.createScreenCapture(new Rectangle(1280,720));
        picLabel.setIcon(new ImageIcon(screenShot));   
    
    }
    

    If you want to paint using Graphics(in this case it's probably a better idea), you can extend a JLabel and override paintComponent method, drawing the image inside it:

    public class ScreenShotPanel extends JLabel
    {
    
        @override
        public void paintComponent(Graphics g) {
            BufferedImage screenShot = robot.createScreenCapture(new Rectangle(1280,720));
            g.drawImage(screenShot,0,0,this);
        }
    }