所以我可以用PIL来抓取桌面的截图,然后用pywin32来获取它的矩形,然后裁剪出我想要的部分。但是,如果我想要的窗口前面有东西,就会遮挡住我想要截图的应用程序。有什么办法可以获得窗口会说一个应用程序当前正在显示的内容吗?它在某个地方有这个数据,即使其他窗口在它前面。
我也做过同样的事情,在拍摄前给我想要的应用程序对焦。
shell=win32com.client.Dispatch("Wscript.Shell")
success = shell.AppActivate(app_name) # Returns true if focus given successfully.
有一个方法可以做到这一点,使用... ... PrintWindow
功能。它使窗口在另一个表面上重新绘制。
我在这里的答案中发布了工作代码。不活动窗口的Python截图. 它使用的是 PrintWindow
函数.这是复制隐藏窗口图像的 "正确 "方法,但这并不意味着它永远有效。这取决于实现正确信息的程序。WM_Print
响应。
如果您尝试使用 PrintWindow
它不工作,那么你唯一剩下的选择将是把窗口到前面,然后再采取的一个 BitBlit
.
如果可以的话,尝试保存窗口的顺序,然后将你的应用程序移动到前面,截图,然后快速将其移回来。可能会产生一点烦人的闪烁,但总比没有好。
也许你可以把应用定位在屏幕外,然后截图,再放回去?
IIRC,在Windows pre-vista中没有--在Aero中,每个窗口都有自己的缓冲区,但在那之前,你只需要使用你的方法,得到矩形。我不确定pywin32是否支持Aero。
这段代码对我来说是在后台应用,而不是最小化的情况下工作的。
pip install pywin32
import win32gui
import win32ui
def background_screenshot(hwnd, width, height):
wDC = win32gui.GetWindowDC(hwnd)
dcObj=win32ui.CreateDCFromHandle(wDC)
cDC=dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, width, height)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0,0),(width, height) , dcObj, (0,0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, 'screenshot.bmp')
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
hwnd = win32gui.FindWindow(None, windowname)
background_screenshot(hwnd, 1280, 780)