Снимок экрана в 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
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]
Решение вашей проблемы находится прямо перед вами, попробуйте думать по-другому. Вам не нужно использовать 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"
каталог.
Надеюсь это поможет.