【问题标题】:Dimensions of screenshot doesn't match dimensions of resized window in Pywin32屏幕截图的尺寸与 Pywin32 中调整大小的窗口的尺寸不匹配
【发布时间】:2021-05-25 04:19:16
【问题描述】:

我正在尝试使用 pywin32 截取 Microsoft Edge 窗口。然后,此屏幕截图将用于机器学习算法以在 Microsoft Edge 中玩游戏。正如您可能猜到的那样,该程序将多次截取屏幕截图,因此我需要尽可能快地截取屏幕截图。为了提高速度,我的程序会将 Microsoft Edge 窗口的大小调整为较小的分辨率(特别是 600 x 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.MoveWindow(hwnd, 0, 0, width, height, True) 移动并调整所需窗口的大小(取自win32gui.GetForegroundWindow())然后,它尝试通过获取整个桌面窗口(@98​​7654325@)来截取窗口,然后将其裁剪到所需的坐标(mem_dc.BitBlt((0, 0), (width, height), img_dc, (left, top),win32con.SRCCOPY) )。然后,我将 win32 屏幕截图转换为 PIL 图像,以便查看。请注意,所需的坐标与最初用于移动窗口的坐标相同。但是,当我尝试运行此程序时,屏幕截图并没有捕获整个窗口!

我曾尝试查看MoveWindowBitBlt 函数的文档,但找不到问题所在。由于 MoveWindow 函数,目标和源矩形参数假定为 (0,0)。宽度和高度参数相同。我也尝试过使用bRepaint 参数,但没有任何区别。

有什么建议吗?


【问题讨论】:

  • 我建议使用 PIl 的 ImageGrab 模块,它非常快(并且易于使用)。
  • 我考虑过,但听说win32更快
  • 过早优化是万恶之源……
  • 我需要优化一切,因为我将它用于 ML 应用程序
  • 让它工作,然后在必要时进行优化。

标签: python image winapi screenshot pywin32


【解决方案1】:

在对这个问题进行了一点尝试之后,我终于找到了问题所在。 在 cmets 中,我说 ctypes.windll.shcore.SetProcessDpiAwareness(1) 不起作用。然而,它做到了。当我放大高度和宽度时,屏幕截图和窗口之间的尺寸非常适合。但是,宽度和高度不适用于较小尺寸的原因(我最初将宽度和高度设置为 500)是因为 Microsoft Edge 不允许这样做。如果宽度在某个阈值内,则窗口的实际宽度将达到 Microsoft Edge 想要的最小宽度。一个简单的解决方法是将宽度和高度设置为更大的分辨率,它起作用了!

非常感谢 cmets 中的每个人,尤其是 @IInspectable。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 2012-12-28
    • 2012-01-27
    • 1970-01-01
    • 2015-02-28
    相关资源
    最近更新 更多