Сделайте снимок экрана приложения переднего плана в Windows с помощью Java без лишних краев

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

void startScreencapture(){
    RECT dimensionsOfWindow = new RECT();
    User32.INSTANCE.GetWindowRect(User32.INSTANCE.GetForegroundWindow(), dimensionsOfWindow );//now in the dimensionsOfWindow you have the dimensions
    Robot robot = new Robot();
    buf = robot.createScreenCapture( dimensionsOfWindow.toRectangle() );
}

public interface User32 extends StdCallLibrary {
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
    HWND GetForegroundWindow();  // add this
    int GetWindowTextA(PointerType hWnd, byte[] lpString, int nMaxCount);
    public boolean GetWindowRect(HWND hWnd, RECT rect);
}

Я получаю скриншоты переднего плана, как показано ниже Сделайте снимок экрана приложения переднего плана в Windows с помощью Java без лишних краев

Если вы заметили, на скриншоте есть дополнительное изображение на границе окна.

Мне не нужна дополнительная часть изображения с моим скриншотом.

Можно ли как-то манипулировать

User32.INSTANCE.GetForegroundWindow()

чтобы я получил скриншот без лишней части?

Я чувствую, что ответ в этой ссылке должен работать. В чем разница между GetClientRect и GetWindowRect в WinApi?

Но когда я заменяю GetWindowRect на GetClientRect, я получаю скриншот ниже: Сделайте снимок экрана приложения переднего плана в Windows с помощью Java без лишних краев

В идеале я должен был получить скриншот только приложения переднего плана.

Редактировать: Даниэль Виддис любезно нашел для меня похожий вопрос: getwindowrect-возвращает-размер-включая-невидимые-границы

У этого есть возможный ответ, т. Е. Получите толщину границы в Windows 10 и отрегулируйте эту толщину, чтобы получить снимок экрана, который я хочу. Но этот ответ использует DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT)); который, возможно, является кодом C.

Если я смогу найти, как найти толщину границы в Java, это решит мою проблему.

Возможный дубликат GetWindowRect возвращает размер, включая «невидимые» границы

Daniel Widdis 15.04.2019 19:20

Вся цель JNA — сделать C-код доступным! :) Если функция еще не встроена в JNA, вы можете добавить интерфейс для ее объявления.

Daniel Widdis 16.04.2019 16:31
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
352
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

GetClientRect:

The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).

Это относительная система координат.

Вы также должны вызвать КлиентТоЭкран, чтобы преобразовать координату клиента в координату экрана.

Обратите внимание, что ClientToScreen получает только параметр POINT (не RECT), и вы можете найти класс POINTздесь.

Обновлено:

GetWindowRect получит «дополнительный» размер. Однако GetClientRect точно не включает его (и другую дополнительную информацию, такую ​​как строка заголовка, граница окна и т. д.).

Это не отвечает на вопрос пользователя, как избавиться от (прозрачной) границы.

Daniel Widdis 16.04.2019 05:45

Я пробовал с ClientToScreen, но для этого требуется int POINT. Я попытался передать его RECT.LEFT и RECT.RIGHT. Но результаты были такими же.

Pramod 16.04.2019 07:44

@Daniel Widdis, GetClientRect точно не включает (невидимые) границы и строку заголовка, границу окна и т. д.

Drake Wu 16.04.2019 08:17

@Promod, вам нужны новые 2 POINTs: {слева, сверху} и {справа, снизу}, чтобы перейти от координат клиента к координатам экрана. но не только прохождение int. Кстати, Двмжетвиндоватрибуте, о котором вы говорили, является win32api.

Drake Wu 16.04.2019 08:24

@DrakeWu-MSFT Пробовал, как вы упомянули, но все равно не работает. пример кода: User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.left); User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.right); User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.top); User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.bottom);

Pramod 16.04.2019 08:47

Нет, вы должны POINT pt1 = new Point (RECT.LEFT, RECT.TOP);, а затем User32.INSTANCE.ClientToScreen(hwnd, pt1); то же, что и pt2 (ПРЯМО.ПРАВО, ПРЯМО.НИЗ). Наконец, сбросьте значение RECT dimensionsOfWindow в соответствии с POINT.

Drake Wu 16.04.2019 08:50

Это сделало это. Я благодарю вас за ваше время и смирение за ответ на мой вопрос.

Pramod 16.04.2019 11:54

@DrakeWu-MSFT спасибо за разъяснения. Я думаю, что, должно быть, пропустил различие между клиентом и окном при первом чтении.

Daniel Widdis 16.04.2019 16:31

Спасибо @DrakeWu-MSFT. Но использование DwmGetWindowAttribute не решило мою проблему. Используя ClientToScreen, как вы предложили. Не могли бы вы добавить это в ответ. Я не нашел ответа, в котором упоминалось бы, как использовать POINT в своих ответах. В принципе, я не смог использовать DwmGetWindowAttribute .

Pramod 18.04.2019 09:53

@Promod Вы тестировали образец в этом связь? используя класс ТОЧКА в com.sun.jna.platform.win32.WinDef.POINT

Drake Wu 18.04.2019 11:28

@DrakeWu-MSFT Да. Я использовал то же самое в своем коде, и это сработало.

Pramod 18.04.2019 11:46

@Promod изменил это. А у вас не получается получить функцию DwmGetWindowAttribute или она не работает?

Drake Wu 18.04.2019 12:01

@DrakeWu-MSFT Я могу получить эту функцию. Я попытался создать для него абстрактный метод в интерфейсе, но не мог придумать, какой параметр я должен передать, например DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT)); Что я должен передать вместо DWMWA_EXTENDED_FRAME_BOUNDS и `sizeof(RECT)` в Java?

Pramod 18.04.2019 12:15

@Promod DWMWA_EXTENDED_FRAME_BOUNDS = 9 и sizeof(RECT) = 16, Вы можете попробовать пройти 9 и 16 напрямую.

Drake Wu 18.04.2019 12:29

@DrakeWu-MSFT хорошо. Спасибо за помощь. Мой текущий код работает, поэтому я не буду его трогать. Но это весьма полезно для людей с такими же проблемами.

Pramod 18.04.2019 12:36

Другие вопросы по теме