Taking Screenshots Using Java – 使用Java进行截图

最后修改: 2020年 7月 31日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

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

在本教程中,我们将看看在Java中进行截图的几种不同方法。

2. Taking a Screenshot Using Robot

2.使用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:

为此,我们将使用createScreenCapture()方法,它来自Robot类。它需要一个Rectangle作为参数来设置屏幕截图的边界,并返回一个BufferedImage对象。这个BufferedImage可以进一步用来创建一个图像文件。

@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.

屏幕的尺寸可以通过Toolkit类中的getScreenSize()方法来访问。在有多个屏幕的系统中,默认使用主显示器。

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.

在将屏幕捕捉到BufferedImage中后,我们可以用ImageIO.write()将其写入文件中。要做到这一点,我们需要两个额外的参数。图像格式和图像文件本身。在我们的例子中,我们使用的是.bmp格式,但其他格式如.png、.jpg.gif也可用。

3. Taking a Screenshot of Multiple Screens

3.对多个屏幕进行截图

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.

也可以同时对多个显示器进行截图。就像前面的例子一样,我们可以使用Robot类中的createScreenCapture()方法。但是这一次,截图的范围需要覆盖所有需要的屏幕。

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

为了获得所有的显示器,我们将使用GraphicsEnvironment类和其getScreenDevices()方法。

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

接下来,我们将获取每个单独屏幕的边界,并创建一个适合所有屏幕的Rectangle

@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.

进一步说,我们需要保存屏幕截图的图像。如同前面的例子,我们可以使用ImageIO.write()方法。

4. Taking a Screenshot of a Given GUI Component

4.对一个给定的GUI组件进行屏幕截图

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

我们也可以对一个给定的UI组件进行屏幕截图。

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

尺寸可以通过getBounds()方法轻松访问,因为每个组件都知道其尺寸和位置。

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:

在这种情况下,我们不打算使用Robot API。相反,我们将使用Component类中的paint()方法,它将直接把内容画到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.

在得到组件的绑定后,我们需要创建BufferedImage.。为此,我们需要宽度、高度和图像类型。在本例中,我们使用BufferedImage.TYPE_INT_ARGB,它指的是一个8位彩色图像。

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.

然后我们继续调用paint()方法来填充BufferedImage,和之前的例子一样,我们用ImageIO.write()方法把它保存到文件中。

5. Conclusion

5.总结

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

在本教程中,我们已经了解了如何使用Java进行屏幕截图的几种方法。

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

与往常一样,本教程中包含所有示例的源代码可在GitHub上获得over