我试图用pywin32截图一个Microsoft窗口。然后,该屏幕截图将用于机器学习算法,以便在Microsoft中玩游戏。正如您可能猜到的,这个程序将多次拍摄截图,所以我需要屏幕截图尽可能快。为了提高速度,我的程序将调整Microsoft窗口的大小,使其具有较小的分辨率(具体而言,为600×600)。但是,当屏幕截图没有显示整个窗口时,即使我已经将它移到了指定的位置。
我的节目:
import win32gui
import win32ui
import win32con
import win32api
from PIL import Image
import time
# grab a handle to the main desktop window
hdesktop = win32gui.GetDesktopWindow()
# determine the size of all monitors in pixels
width = 600
height = 600
left = 0
top = 0
# set window to correct location
print("You have 3 second to click the desired window!")
for i in range(3, 0, -1):
print(i)
time.sleep(1)
hwnd = win32gui.GetForegroundWindow()
win32gui.MoveWindow(hwnd, 0, 0, width, height, True)
# create a device context
desktop_dc = win32gui.GetWindowDC(hdesktop)
img_dc = win32ui.CreateDCFromHandle(desktop_dc)
# create a memory based device context
mem_dc = img_dc.CreateCompatibleDC()
# create a bitmap object
screenshot = win32ui.CreateBitmap()
screenshot.CreateCompatibleBitmap(img_dc, width, height)
mem_dc.SelectObject(screenshot)
# copy the screen into our memory device context
mem_dc.BitBlt((0, 0), (width, height), img_dc, (left, top),win32con.SRCCOPY)
bmpinfo = screenshot.GetInfo()
bmpstr = screenshot.GetBitmapBits(True)
im = Image.frombuffer(
'RGB',
(bmpinfo['bmWidth'], bmpinfo['bmHeight']),
bmpstr, 'raw', 'BGRX', 0, 1)
im.show()
# free our objects
mem_dc.DeleteDC()
win32gui.DeleteObject(screenshot.GetHandle())
我的程序首先通过win32gui.GetForegroundWindow()
移动和调整所需的窗口(从win32gui.MoveWindow(hwnd, 0, 0, width, height, True)
获取),然后尝试通过获取整个桌面窗口(hdesktop = win32gui.GetDesktopWindow()
)并将其裁剪到所需的坐标(mem_dc.BitBlt((0, 0), (width, height), img_dc, (left, top),win32con.SRCCOPY)
)来截取窗口。然后,我将win32截图转换为PIL图像,这样我就可以查看它了。请注意,所需的坐标是用于移动窗口的相同坐标。然而,当我试图运行这个程序时,屏幕截图并不能捕捉到整个窗口!
我试过查看MoveWindow
和BitBlt
函数的文档,但找不到问题。目标和源矩形参数应该是(0,0),因为是MoveWindow
函数。宽度和高度参数是相同的。我也尝试过使用bRepaint
参数,但这并没有什么不同。
有什么建议吗?
发布于 2021-05-24 20:19:16
在尝试了这个问题之后,我终于发现了这个问题。在评论中,我说ctypes.windll.shcore.SetProcessDpiAwareness(1)
不起作用。然而,它做到了。当我放大高度和宽度时,截图和窗口之间的尺寸就完全吻合了。但是,宽度和高度不适用于较小尺寸的原因(我最初将宽度和高度设置为500)是因为Microsoft不允许使用。如果宽度在某个阈值内,则窗口的实际宽度将降到Microsoft Edge希望的最小宽度。一个简单的工作是把宽度和高度设置成一个更大的分辨率,它起作用了!
非常感谢评论中的每一个人,特别是@IInspectable。
https://stackoverflow.com/questions/67550294
复制相似问题