javawindowsscreen-capture

Screen Capture during lockscreen using java on windows


The aim is to do screen capture regardless of screen lock as long as the java application is running. I have come across several similar questions on the exchange but all of them relate to using Selenium or some Windows specific code.

The code (see below) uses java.awt.Robot to do looped screen capture. The file is saved as a png.

The problem is when a user locks the computer, the screenshot taken is of the lockscreen instead of what the underlying screen would look like if the pc was unlocked.

How to solve this?

import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class Capture{
    public static void main(String[] args) throws Exception {
        GraphicsDevice screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        DisplayMode dm = screen.getDisplayMode();
        int[] size = {dm.getWidth(), dm.getHeight()};
        Rectangle rect = new Rectangle(size[0], size[1]);
        String path = "D:/img.png";
        Robot rob = new Robot(screen);
        File outfile = new File(path);

        while (true) {
            BufferedImage img = rob.createScreenCapture(rect);
            ImageIO.write(img, "png", outfile);
            Thread.sleep(1000);
        }

    }

}

env
Windows 10
JDK 12


Solution

  • Portably capturing the underlying application during lockscreen is impossible to do in Java, and perhaps in any screen capturing solution. Docs for Robot.createScreenCapture say:

    "[It] Creates an image containing pixels read from the screen. ..."

    implying that Robot is only capable of capturing whatever is being rendered to the screen and has no notion/understanding/programmatic ability to detect its contents, say individual applications, notifications, widgets etc. When what is being rendered is the lockscreen, that is what gets captured.

    This also implies that when nothing is being sent to it (say the monitor/screen was turned off by the OS's energy policy and so wasn't necessarily being rendered to), nothing (but perhaps a black screen) gets captured.

    In order to achieve what you are attempting,you need application specific hooks either into the app (say via some API it exposes - highly unlikely) or an OS specific call (e.g.) or process probing. Former depends on the app and the latter break portability.

    Remark on general impossibility: Video conferencing/streaming/screen recording/remote access apps routinely share app specific screens across users. However, an app's ('the recorder') app-agnostic awareness of and access to other applications ('the recorded') is necessarily mediated by the OS, thus breaking portability. Not to mention it stops during lockscreen.

    This would be equally true of audio capture or any other data stream. As a maxim, then:

    Cross app-data capture is either exposed by target app or is OS mediated.