Is there a way to take a screenshot using Java and save it to some sort of image?

136,801

Solution 1

Believe it or not, you can actually use java.awt.Robot to "create an image containing pixels read from the screen." You can then write that image to a file on disk.

I just tried it, and the whole thing ends up like:

Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
ImageIO.write(capture, "bmp", new File(args[0]));

NOTE: This will only capture the primary monitor. See GraphicsConfiguration for multi-monitor support.

Solution 2

I never liked using Robot, so I made my own simple method for making screenshots of JFrame objects:

public static final void makeScreenshot(JFrame argFrame) {
    Rectangle rec = argFrame.getBounds();
    BufferedImage bufferedImage = new BufferedImage(rec.width, rec.height, BufferedImage.TYPE_INT_ARGB);
    argFrame.paint(bufferedImage.getGraphics());

    try {
        // Create temp file
        File temp = File.createTempFile("screenshot", ".png");

        // Use the ImageIO API to write the bufferedImage to a temporary file
        ImageIO.write(bufferedImage, "png", temp);

        // Delete temp file when program exits
        temp.deleteOnExit();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

Solution 3

If you'd like to capture all monitors, you can use the following code:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();

Rectangle allScreenBounds = new Rectangle();
for (GraphicsDevice screen : screens) {
    Rectangle screenBounds = screen.getDefaultConfiguration().getBounds();

    allScreenBounds.width += screenBounds.width;
    allScreenBounds.height = Math.max(allScreenBounds.height, screenBounds.height);
}

Robot robot = new Robot();
BufferedImage screenShot = robot.createScreenCapture(allScreenBounds);

Solution 4

public void captureScreen(String fileName) throws Exception {
   Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
   Rectangle screenRectangle = new Rectangle(screenSize);
   Robot robot = new Robot();
   BufferedImage image = robot.createScreenCapture(screenRectangle);
   ImageIO.write(image, "png", new File(fileName));
}

Solution 5

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();  
GraphicsDevice[] screens = ge.getScreenDevices();       
Rectangle allScreenBounds = new Rectangle();  
for (GraphicsDevice screen : screens) {  
       Rectangle screenBounds = screen.getDefaultConfiguration().getBounds();        
       allScreenBounds.width += screenBounds.width;  
       allScreenBounds.height = Math.max(allScreenBounds.height, screenBounds.height);
       allScreenBounds.x=Math.min(allScreenBounds.x, screenBounds.x);
       allScreenBounds.y=Math.min(allScreenBounds.y, screenBounds.y);
      } 
Robot robot = new Robot();
BufferedImage bufferedImage = robot.createScreenCapture(allScreenBounds);
File file = new File("C:\\Users\\Joe\\Desktop\\scr.png");
if(!file.exists())
    file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ImageIO.write( bufferedImage, "png", fos );

bufferedImage will contain a full screenshot, this was tested with three monitors

Share:
136,801
jjnguy
Author by

jjnguy

About Me: I currently work for Design Center as a Sr. Software Engineer. Follow me on Twitter If you want to contact me personally, email me or send me a private message on twitter. jjnguy13 [at]gmail[dot] com

Updated on November 01, 2020

Comments

  • jjnguy
    jjnguy over 3 years

    Simple as the title states: Can you use only Java commands to take a screenshot and save it? Or, do I need to use an OS specific program to take the screenshot and then grab it off the clipboard?

  • Chris Wagner
    Chris Wagner about 14 years
    I wonder if this is what screen sharing applications like Elluminate (elluminate.com) use.
  • Simon Forsberg
    Simon Forsberg almost 12 years
    Any reason for why you're not liking Robot?
  • Dmitry Zagorulkin
    Dmitry Zagorulkin over 11 years
    @java_enthu actually yes, it will be work without console if you will hardcode path to screenshot in your app.
  • nullUser
    nullUser almost 11 years
    Robot does not include the mouse in the screen capture. Is there a similar function which does the exact same thing, but DOES include the mouse?
  • Mehdi Karamosly
    Mehdi Karamosly over 10 years
    is there a way to capture the mouse cursor as well ?!
  • DejanLekic
    DejanLekic over 10 years
    Think of it simply as a matter of taste.
  • Brad Mace
    Brad Mace almost 10 years
    would be better to calculate it this way
  • Brad Mace
    Brad Mace almost 10 years
    It looks like this should have the advantage of working even if the target window is obscured before the screenshot is taken.
  • Brad Mace
    Brad Mace almost 10 years
    On the other hand, this gets only the contents of the window, whereas with Robot you can also get the window's frame and titlebar.
  • DejanLekic
    DejanLekic about 8 years
    @BradMace: that is a good point. I did not need the frame and titlebar, just the content...
  • Liam Larsen
    Liam Larsen almost 7 years
    I did a benchmark and this one is the slowest, also has the greatest loss and biggest file size. Sorry,
  • nyholku
    nyholku almost 7 years
    For HiDPI (Mac retina) displays this creates screenshots at half resolution. To fix that bufferedImage.getGraphics().scale(2, 2) before the argFrame.paint(bufferedImage.getGraphics()) call and use new BufferedImage(rec.width*2, rec.height*2, BufferedImage.TYPE_INT_ARGB) to create the BufferedImage