«1. Введение

В этом руководстве мы рассмотрим несколько различных способов создания снимка экрана в Java.

2. Создание скриншота с помощью робота

В нашем первом примере мы собираемся сделать скриншот главного экрана.

Для этого воспользуемся методом 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());
}

Размеры экрана доступны через класс Toolkit с помощью его метода getScreenSize(). В системах с несколькими экранами по умолчанию используется основной дисплей.

После захвата экрана в BufferedImage мы можем записать его в файл с помощью ImageIO.write(). Для этого нам понадобятся два дополнительных параметра. Формат изображения и сам файл изображения. В нашем примере мы используем формат .bmp, но также доступны другие форматы, такие как .png, .jpg или .gif.

3. Снимок экрана нескольких экранов

Также можно сделать снимок экрана нескольких дисплеев одновременно. Как и в предыдущем примере, мы можем использовать метод createScreenCapture() из класса Robot. Но на этот раз границы скриншота должны охватывать все необходимые экраны.

Чтобы получить все изображения, мы будем использовать класс GraphicsEnvironment и его метод getScreenDevices().

Далее мы собираемся получить границу каждого отдельного экрана и создать прямоугольник, который будет соответствовать всем им:

@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());
}

Перебирая дисплеи, мы всегда суммируем ширину и выбираем только один максимальная высота, так как экраны будут объединены по горизонтали.

Идя дальше, нам нужно сохранить изображение скриншота. Как и в предыдущем примере, мы можем использовать метод ImageIO.write().

4. Создание скриншота данного компонента графического интерфейса

Мы также можем сделать скриншот данного компонента пользовательского интерфейса.

Доступ к размерам можно легко получить с помощью метода getBounds(), поскольку каждый компонент знает о своем размере и расположении.

В этом случае мы не будем использовать Robot API. Вместо этого мы собираемся использовать метод paint() из класса Component, который будет рисовать содержимое непосредственно в 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());
}

После получения привязки компонента нам нужно создать BufferedImage. Для этого нам нужны ширина, высота и тип изображения. В данном случае мы используем BufferedImage.TYPE_INT_ARGB, который относится к 8-битному цветному изображению.

Затем мы переходим к вызову метода paint() для заполнения BufferedImage и, как и в предыдущих примерах, сохраняем его в файл с помощью метода ImageIO.write().

5. Заключение

В этом уроке мы узнали несколько способов делать скриншоты с помощью Java.

Как всегда, исходный код со всеми примерами из этого руководства доступен на GitHub.