Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

In this tutorial, we'll take a look at a few different ways of taking a screenshot in Java.

2. Taking a Screenshot Using Robot

In our first example, we're going to take a screenshot of the main screen.

For that, we'll use the createScreenCapture() method from the Robot class. It takes a Rectangle as a parameter that sets the bounds for the screenshot and returns a BufferedImage object. The BufferedImage can be further used to create an image file:

@Test
public void givenMainScreen_whenTakeScreenshot_thenSaveToFile() throws Exception {
    Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
    BufferedImage capture = new Robot().createScreenCapture(screenRect);

    File imageFile = new File("single-screen.bmp");
    ImageIO.write(capture, "bmp", imageFile );
    assertTrue(imageFile .exists());
}

The dimensions of the screen are accessible through the Toolkit class by using its getScreenSize() method. On systems with multiple screens, the primary display is used by default.

After capturing the screen into BufferedImage, we can write it to the file with ImageIO.write(). To do so, we'll need two additional parameters. The image format and the image file itself. In our example, we're using the .bmp format, but others like .png, .jpg or .gif are also available.

3. Taking a Screenshot of Multiple Screens

It's also possible to take a screenshot of multiple displays at once. Just like with the previous example, we can use the createScreenCapture() method from the Robot class. But this time the bounds of the screenshot need to cover all required screens.

In order to get all of the displays, we'll use the GraphicsEnvironment class and its getScreenDevices() method.

Next, we're going to fetch the bound of each individual screen and create a Rectangle that will fit all of them:

@Test
public void givenMultipleScreens_whenTakeScreenshot_thenSaveToFile() throws Exception {
    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);
    }

    BufferedImage capture = new Robot().createScreenCapture(allScreenBounds);
    File imageFile = new File("all-screens.bmp");
    ImageIO.write(capture, "bmp", imageFile);
    assertTrue(imageFile.exists());
}

While iterating over the displays, we always sum up the widths and choose just one maximum height as the screens will be concatenated horizontally.

Going further we need to save the screenshot image. As in the previous example, we can use the ImageIO.write() method.

4. Taking a Screenshot of a Given GUI Component

We can also take a screenshot of a given UI component.

The dimensions can be easily accessed via the getBounds() method as every component is aware of its size and location.

In this case, we're not going to use the Robot API. Instead, we're going to use the paint() method from the Component class that will draw the content directly into the BufferedImage:

@Test
public void givenComponent_whenTakeScreenshot_thenSaveToFile(Component component) throws Exception {
    Rectangle componentRect = component.getBounds();
    BufferedImage bufferedImage = new BufferedImage(componentRect.width, componentRect.height, BufferedImage.TYPE_INT_ARGB);
    component.paint(bufferedImage.getGraphics());

    File imageFile = new File("component-screenshot.bmp");
    ImageIO.write(bufferedImage, "bmp", imageFile );
    assertTrue(imageFile.exists());
}

After getting the component's bound we need to create the BufferedImage. For this, we need the width, height, and image type. In this case, we're using BufferedImage.TYPE_INT_ARGB which refers to an 8-bit color image.

We then move forward to invoke the paint() method to fill the BufferedImage and same as in previous examples we're saving it to a file with ImageIO.write() method.

5. Conclusion

In this tutorial, we've learned several ways how to take screenshots using Java.

As always the source code with all the examples in this tutorial is available over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
guest
0 Comments
Inline Feedbacks
View all comments