How to Get a Window or Fullscreen Screenshot in Python 3k? (without PIL)
Here's how you can do it using PIL on win32. Given a window handle (hwnd
), you should only need the last 4 lines of code. The preceding simply search for a window with "firefox" in the title. Since PIL's source is available, you should be able to poke around the ImageGrab.grab(bbox)
method and figure out the win32 code you need to make this happen.
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()
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]