Python 非活动屏幕截图

Posted

技术标签:

【中文标题】Python 非活动屏幕截图【英文标题】:Python inactive screen capture 【发布时间】:2018-09-13 07:47:28 【问题描述】:

我想用 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。

截图:

如果您有任何解决方案,请帮助我。

【问题讨论】:

Using ImageGrab with bbox from pywin32's GetWindowRect的可能重复 【参考方案1】:

这里的部分问题是Using ImageGrab with bbox from pywin32's GetWindowRect 中描述的 DPI 设置,但由于GetWindowRect too small on Windows 7 中描述的 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://***.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 应该有正确的边界。

【讨论】:

以上是关于Python 非活动屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章

共享屏幕截图的活动控制器显示为空

TestNG 中的非静态驱动程序和屏幕截图侦听器

当我的应用在IOS中处于活动状态时如何阻止屏幕截图[关闭]

为啥在firebase onAuthStateChanged中完成活动时最近的应用程序中没有屏幕截图

在不同的资源文件中截取布局的屏幕截图

MacOS中某些应用程序的Java屏幕截图