Снимок экрана на Java (робот, код работает, но не с внешним полноэкранным приложением)

Я использую следующий код для создания снимка экрана:

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

Этот код работает нормально. Он делает снимки экрана моего рабочего стола, когда я запускаю программу и т. Д.

Однако, когда я пытаюсь запустить первую игру или приложение в полноэкранном режиме, они не работают должным образом. Отображает либо черный экран, либо ту же «начальную» картинку.

Известна ли эта проблема, и как ее исправить?

Второй вопрос: Можно ли имитировать какую-то клавишу «Print Screen», которую мы можем иметь на клавиатуре, чтобы решить эту проблему? Потому что я могу использовать клавишу Print Screen, когда приложение запускается в полноэкранном режиме, и когда я вставляю, я получаю свой экран.
(Как это, но в java: Скопируйте содержимое экрана или активного окна?)

Спасибо заранее за вашу помощь.

ИЗМЕНИТЬ: Эндрю Томпсон любезно предложил мне следующий код, который станет первым хорошим шагом к решению этой проблемы:

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

}

Он хорошо компилируется, но при его запуске появляется следующая ошибка.

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

person user1638875    schedule 03.09.2012    source источник
comment
Это может быть особенностью самой игры, что в ней есть механизмы, предотвращающие создание или запуск кодировщиков ботов и, таким образом, не позволяющие им получить несправедливое преимущество.   -  person Hovercraft Full Of Eels    schedule 03.09.2012
comment
В моем случае совсем нет. Кроме того, мы можем сделать несколько снимков экрана с помощью PRINT SCREEN.   -  person user1638875    schedule 03.09.2012
comment
Похоже, вы используете функцию ScreenCapture, встроенную в библиотеку роботов. Где взять эту библиотеку роботов?   -  person apnorton    schedule 03.09.2012
comment
@ anorton: здесь: docs.oracle.com /javase/1.4.2/docs/api/java/awt/Robot.html   -  person user1638875    schedule 03.09.2012
comment
@user: возможно, вы слишком много предполагаете. Да, это может быть проблемой даже с вашей способностью использовать экран для печати.   -  person Hovercraft Full Of Eels    schedule 03.09.2012


Ответы (2)


Известна ли эта проблема, ..

да. Обычно это вызвано перемещением рендеринга на уровень самой видеокарты (в значительной степени отодвигая ОС).

..а как исправить пожалуйста?

AFAIU это не может быть исправлено. Даже родные приложения для скриншотов. получить скриншот такого рендера не получится.

Можно ли имитировать какую-то клавишу "Print Screen", чтобы решить эту проблему?

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

Выход

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]
person Andrew Thompson    schedule 03.09.2012
comment
Так почему я могу использовать экранную клавишу Print? Есть ли способ использовать эту функцию в моем Java-коде, пожалуйста? Кроме того, когда я не запускаю приложение в полноэкранном режиме, моя программа работает правильно. - person user1638875; 03.09.2012
comment
Но не забудьте отпустить и ключ! - person Hovercraft Full Of Eels; 03.09.2012
comment
@ Эндрю Томпсон: Спасибо! Теперь я пытаюсь объединить его с bufferedImage, в моем случае создаю image = robot.keyPress (KeyEvent.VK_PRINTSCREEN); не работает. @ HoverCraft Full Of Eels: что вы имеете в виду под выпуском? - person user1638875; 03.09.2012
comment
facepalms --- Он имеет в виду, что, как и в случае с физическим взаимодействием, клавиша, которая логически опускается, также должна возвращаться; В противном случае у вас застрял ключ. --- @ user1638875 И image = robot.keyPress(KeyEvent.VK_PRINTSCREEN); не будет работать, потому что сам по себе не служит целям, связанным с данными; Результат исходит не от самого метода, а от его воздействия на окружающую среду. Короче говоря, ваш снимок экрана не возвращается методом, а сохраняется в памяти буфера обмена, откуда вы должны получить его другими способами. - person XenoRo; 03.09.2012
comment
Я нашел в Интернете метод getClipboard (), но он кажется очень старым и не работает. - person user1638875; 03.09.2012
comment
Спасибо за помощь. Мне было интересно, есть ли способ сохранить этот аромат данных, например, как файл png? - person user1638875; 04.09.2012
comment
В конце строки написано, что это java.awt.Image, так что да, это относительно просто. Если вы не можете узнать, как это сделать, вам следует задать новый вопрос. Кстати, примите этот ответ, когда у вас будет возможность. - person Andrew Thompson; 04.09.2012
comment
Обещаю, я сделаю это, но пока у меня возникла ошибка: java.awt.datatransfer.DataFlavor [mimetype = text / plain; presentationclass = java.nio.ByteBuffer; charset = US-ASCII] java.awt.datatransfer.DataFlavor [mimetype = text / plain; класс представления = [B; кодировка = US-ASCII] септ. 04, 2012 13:45:36 pack.main перейти в СЕРЬЕЗНУЮ: null java.lang.NullPointerException - person user1638875; 04.09.2012
comment
Ошибка, указанная в отдельном классе: Исключение в основном потоке java.lang.IllegalStateException: невозможно открыть системный буфер обмена в sun.awt.windows.WClipboard.openClipboard (собственный метод) в sun.awt.datatransfer.SunClipboard.getClipboardFormatsOpenClose (SunClipboard.java : 332) по адресу sun.awt.datatransfer.SunClipboard.getAvailableDataFlavors (SunClipboard.java:172) - person user1638875; 04.09.2012
comment
Я не могу (даже не пытаюсь) прочитать код или вывод исключения в комментариях. Отредактируйте его в вопросе, используя форматирование кода, и сообщите мне. - person Andrew Thompson; 04.09.2012
comment
Вопрос обновлен. Я должен сказать вам огромное спасибо за попытку помочь мне вот так. - person user1638875; 04.09.2012
comment
Для @ user: cb сначала необходимо установить значение NULL, чтобы он очистил все, что связано с буфером обмена, которое может использоваться Windows. Обычно после этого должно работать. - person Arsenic; 04.09.2012
comment
Спасибо !! Теперь работает! Я принял ваш ответ на этот вопрос и попросил еще одного сохранить здесь dataflavor в виде файла png: stackoverflow.com/questions/12264146/, как мне предложил Эндрю Томпсон. Чувствую, что близок к финальной работе :) - person user1638875; 04.09.2012

Решение вашей проблемы прямо перед вами, попробуйте думать по-другому. Вам не нужно использовать функцию PrtScr, потому что почти все платформы (игры) имеют встроенную функцию снимка экрана.

В Steam, например, это включает все игры, в которые можно играть через Steam, F12 используется для создания снимка экрана. Вместо использования PrtScr используйте F12 в своем коде, файл автоматически сохраняется, используйте этот файл, делайте с ним все, что захотите.

Я знаю, что это немного поздно, но я надеюсь, что это поможет вам в вашем проекте.

Отредактируйте, чтобы добавить точный код:

if (e.getKeyCode() == NativeKeyEvent.VC_0) {
    Robot robot = null;
    try {
        robot = new Robot();
        robot.keyPress(KeyEvent.VK_F12);
        robot.keyRelease(KeyEvent.VK_F12);
    } 
    catch (AWTException ex) {
        Logger.getLogger(JavaApplication6.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Это относится к Steam, в основном, когда вы нажимаете «0», ваша программа имитирует ввод F12, это делает снимок экрана, который будет сохранен в каталоге "STEAM\userdata\137637106\760\remote\570\screenshots".

Надеюсь это поможет.

person kmotawaze    schedule 06.12.2014