如何在Python 3k中获取窗口或全屏截图?(没有PIL)

Kob*_*ohn 8 screenshot window python-3.x

使用python 3,我想获得另一个窗口(不是我的应用程序的一部分)的句柄,这样我可以:

a)直接捕获该窗口作为截图或

b)确定其位置和大小并以其他方式捕获它

如果它很重要,我使用的是Windows XP(编辑:也适用于Windows 7).

我找到了这个解决方案,但它不是我需要的,因为它是全屏的,更重要的是,据我所知,PIL还不支持3.x.

ars*_*ars 17

以下是在win32上使用PIL执行此操作的方法.给定一个窗口句柄(hwnd),您应该只需要最后4行代码.前面只是在标题中搜索一个带有"firefox"的窗口.由于PIL的源代码可用,您应该能够找到ImageGrab.grab(bbox)方法并找出实现此目的所需的win32代码.

from PIL import ImageGrab
import win32gui

toplist, winlist = [], []
def enum_cb(hwnd, results):
    winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
win32gui.EnumWindows(enum_cb, toplist)

firefox = [(hwnd, title) for hwnd, title in winlist if 'firefox' in title.lower()]
# just grab the hwnd for first window matching firefox
firefox = firefox[0]
hwnd = firefox[0]

win32gui.SetForegroundWindow(hwnd)
bbox = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox)
img.show()
Run Code Online (Sandbox Code Playgroud)

  • 你可以尝试这个页面上的代码,但我自己没有这样做:http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-05/2531.html (2认同)

Kob*_*ohn 12

Ars给了我所有的碎片.我只是把这些碎片放在这里为其他需要在python 3.x中获取屏幕截图的人.接下来,我需要弄清楚如何使用win32位图而不依赖PIL.

获取屏幕截图(为窗口而不是全屏传递hwnd):

def screenshot(hwnd = None):
    import win32gui
    import win32ui
    import win32con
    from time import sleep
    if not hwnd:
        hwnd=win32gui.GetDesktopWindow()
    l,t,r,b=win32gui.GetWindowRect(hwnd)
    h=b-t
    w=r-l
    hDC = win32gui.GetWindowDC(hwnd)
    myDC=win32ui.CreateDCFromHandle(hDC)
    newDC=myDC.CreateCompatibleDC()

    myBitMap = win32ui.CreateBitmap()
    myBitMap.CreateCompatibleBitmap(myDC, w, h)

    newDC.SelectObject(myBitMap)

    win32gui.SetForegroundWindow(hwnd)
    sleep(.2) #lame way to allow screen to draw before taking shot
    newDC.BitBlt((0,0),(w, h) , myDC, (0,0), win32con.SRCCOPY)
    myBitMap.Paint(newDC)
    myBitMap.SaveBitmapFile(newDC,'c:\\tmp.bmp')
Run Code Online (Sandbox Code Playgroud)

按标题获取窗口句柄(传递给上面的函数):

def _get_windows_bytitle(title_text, exact = False):
    def _window_callback(hwnd, all_windows):
        all_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
    windows = []
    win32gui.EnumWindows(_window_callback, windows)
    if exact:
        return [hwnd for hwnd, title in windows if title_text == title]
    else:
        return [hwnd for hwnd, title in windows if title_text in title]
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉很晚才发表评论,但我发现该窗口似乎根本不位于前景中,无法通过此方法捕获。 (2认同)