我想用win32gui制作一个非活动窗口的屏幕截图。
from PIL import ImageGrab
import win32gui
hwnd = win32gui.FindWindow(None, 'Calculator')
win32gui.SetForegroundWindow(hwnd)
dimensions = win32gui.GetWindowRect(hwnd)
image = ImageGrab.grab(dimensions)
image.show()
但是它没有按预期工作。它可以捕获屏幕区域,但不能完全捕获窗口所在的位置。我也尝试过调整计算器窗口的大小,但没有帮助。如果相关的话,我的屏幕分辨率为1920 * 1080。
屏幕截图:
如果您有任何解决方案,请帮助我。
答案 0 :(得分:1)
这里的部分问题是Using ImageGrab with bbox from pywin32's GetWindowRect中描述的DPI设置,但是由于{{3}中描述的Windows 10功能,win32gui.GetClientRect(hwnd)
返回的矩形周围仍然会有多余的空间。 },据我所读,它开始出现在Windows 8和Aero中。
因此,出于完整性考虑,以下是一种解决方案:
# imports
import win32gui, win32con, ctypes
from PIL import ImageGrab
from ctypes import wintypes
# this takes care of the DPI settings (https://stackoverflow.com/questions/51786794/using-imagegrab-with-bbox-from-pywin32s-getwindowrect)
ctypes.windll.user32.SetProcessDPIAware()
# get window handle and dimensions
hwnd = win32gui.FindWindow(None, 'Calculator')
dimensions = win32gui.GetWindowRect(hwnd)
# this gets the window size, comparing it to `dimensions` will show a difference
winsize = win32gui.GetClientRect(hwnd)
# this sets window to front if it is not already
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST,0,0,0,0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST,0,0,0,0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST,0,0,0,0, win32con.SWP_SHOWWINDOW | win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
# grab screen region set in `dimensions`
image = ImageGrab.grab(dimensions)
image.show()
# we're going to use this to get window attributes
f=ctypes.windll.dwmapi.DwmGetWindowAttribute
# `rect` is for the window coordinates
rect = ctypes.wintypes.RECT()
DWMWA_EXTENDED_FRAME_BOUNDS = 9
# and then the coordinates of the window go into `rect`
f(ctypes.wintypes.HWND(hwnd),
ctypes.wintypes.DWORD(DWMWA_EXTENDED_FRAME_BOUNDS),
ctypes.byref(rect),
ctypes.sizeof(rect)
)
# if we want to work out the window size, for comparison this should be the same as `winsize`
size = (rect.right - rect.left, rect.bottom - rect.top)
# put the window coordinates in a tuple like that returned earlier by GetWindowRect()
dimensions = (rect.left, rect.top, rect.right, rect.bottom)
# grab screen region set in the revised `dimensions`
image = ImageGrab.grab(dimensions)
image.show()
然后image
应该具有正确的边界。