Search code examples
javaawtfullscreenscreenshotawtrobot

Taking screenshot in Java (Robot, code working but not with external full screen application)


I am using the following code for taking a screenshot:

        Robot robot = new Robot();
        BufferedImage image = robot.createScreenCapture(screenRectangle);
        ImageIO.write(image,"png", file);

This code is running good. It takes screen shots of my desktop when I run the program, etc.

However, when I try to run first some game, application in full screen, it doesn't work properly. It renders either black screen, either the same "initial" picture.

Is this problem known, and how to fix this please?

Second question : Is this possible to simulate some "Print Screen" key we can have on keybord in order to solve this problem? Because I can use Print Screen key when the application is launched in full screen, and when I paste I got my screen.
(Like this but in java : Copy the contents of the screen or the active window ? )

Thank you in advance for your help.

EDIT : Andrew Thompson was kind to propose me the following code that will be a good first step to solve this problem :

import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.KeyEvent;

public class ScreenshotUsingPrintScreen {

public static void main(String[] args) throws Exception {
    int i = KeyEvent.VK_PRINTSCREEN;
    Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
    DataFlavor[] flavors = cb.getAvailableDataFlavors();
    System.out.println("Before: ");
    for (DataFlavor flavor : flavors) {
        System.out.println(flavor);
    }

    // get the screenshot
    Robot robot = new Robot();
    robot.keyPress(KeyEvent.VK_PRINTSCREEN);
    robot.delay(40);
    robot.keyRelease(KeyEvent.VK_PRINTSCREEN);
    robot.delay(40);

    cb = Toolkit.getDefaultToolkit().getSystemClipboard();
    flavors = cb.getAvailableDataFlavors();
    System.out.println("After: ");
    for (DataFlavor flavor : flavors) {
        System.out.println(flavor);
    }
}

}

It compiles well but however I receive the following error while then running it.

Before: 
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-text-encoding;representationclass=[B]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.Reader]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.lang.String]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.CharBuffer]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[C]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-16]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-16]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-16]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-8]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-8]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-8]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-16BE]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-16BE]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-16BE]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-16LE]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-16LE]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-16LE]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=ISO-8859-1]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=ISO-8859-1]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=ISO-8859-1]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=US-ASCII]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=US-ASCII]
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=US-ASCII]
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=java.lang.String]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.Reader]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.lang.String]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.CharBuffer]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[C]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=unicode]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-8]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-8]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-8]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-16BE]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16BE]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16BE]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-16LE]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16LE]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16LE]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=ISO-8859-1]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=ISO-8859-1]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=ISO-8859-1]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=US-ASCII]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=US-ASCII]
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=US-ASCII]
Exception in thread "main" java.lang.IllegalStateException: cannot open system clipboard
    at sun.awt.windows.WClipboard.openClipboard(Native Method)
    at sun.awt.datatransfer.SunClipboard.getClipboardFormatsOpenClose(SunClipboard.java:332)
    at sun.awt.datatransfer.SunClipboard.getAvailableDataFlavors(SunClipboard.java:172)
    at zipprotected.threadsTest.ScreenshotUsingPrintScreen.main(ScreenshotUsingPrintScreen.java:36)
Java Result: 1

Solution

  • Is this problem known,..

    Yes. Typically it is caused by moving the rendering down to the level of the graphics card itself (largely side-stepping the OS).

    ..and how to fix this please?

    AFAIU it cannot be fixed. Even native screenshot apps. will not manage to gain a screenshot of such a rendering.

    Is this possible to simulate some "Print Screen" key in order to solve this problem?

    import java.awt.Robot;
    import java.awt.Toolkit;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.event.KeyEvent;
    
    public class ScreenshotUsingPrintScreen {
    
        public static void main(String[] args) throws Exception {
            int i = KeyEvent.VK_PRINTSCREEN;
            Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
            DataFlavor[] flavors = cb.getAvailableDataFlavors();
            System.out.println("Before: ");
            for (DataFlavor flavor : flavors) {
                System.out.println(flavor);
            }
    
            // get the screenshot
            Robot robot = new Robot();
            robot.keyPress(KeyEvent.VK_PRINTSCREEN);
            robot.delay(40);
            robot.keyRelease(KeyEvent.VK_PRINTSCREEN);
            robot.delay(40);
    
            cb = Toolkit.getDefaultToolkit().getSystemClipboard();
            flavors = cb.getAvailableDataFlavors();
            System.out.println("After: ");
            for (DataFlavor flavor : flavors) {
                System.out.println(flavor);
            }
        }
    }
    

    Output

    Before: 
    java.awt.datatransfer.DataFlavor[mimetype=application/x-java-text-encoding;representationclass=[B]
    java.awt.datatransfer.DataFlavor[mimetype=text/rtf;representationclass=java.io.InputStream]
    java.awt.datatransfer.DataFlavor[mimetype=text/rtf;representationclass=java.nio.ByteBuffer]
    java.awt.datatransfer.DataFlavor[mimetype=text/rtf;representationclass=[B]
    java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=java.lang.String]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.Reader]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.lang.String]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.CharBuffer]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[C]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=unicode]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-8]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-8]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-8]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-16BE]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16BE]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16BE]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-16LE]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16LE]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16LE]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=ISO-8859-1]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=ISO-8859-1]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=ISO-8859-1]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=windows-1252]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=windows-1252]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=windows-1252]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=US-ASCII]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=US-ASCII]
    java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=US-ASCII]
    After: 
    java.awt.datatransfer.DataFlavor[mimetype=image/x-java-image;representationclass=java.awt.Image]