Search code examples
windowscreenshotpython-3.x

How to Get a Window or Fullscreen Screenshot (without PIL)?


With python 3, I'd like to get a handle to another window (not part of my application) such that I can either:

  1. directly capture that window as a screenshot, or
  2. determine its position and size and capture it some other way

In case it is important, I am using Windows XP (edit: works in Windows 7 also).

I found this solution, but it is not quite what I need since it is full screen and more importantly, PIL to the best of my knowledge does not support 3.x yet.


Solution

  • Ars gave me all the pieces. I am just putting the pieces together here for anyone else who needs to get a screenshot in python 3.x. Next I need to figure out how to work with a win32 bitmap without having PIL to lean on.

    Get a Screenshot (pass hwnd for a window instead of full screen):

    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')
    

    Get a Window Handle by title (to pass to the above function):

    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]