Skip to content

Instantly share code, notes, and snippets.

@arpruss
Last active January 11, 2018 19:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arpruss/e01e7e05e52d0eb0510a81e34c00569a to your computer and use it in GitHub Desktop.
Save arpruss/e01e7e05e52d0eb0510a81e34c00569a to your computer and use it in GitHub Desktop.
screenshot grabber
import PIL
import PIL.ImageGrab
import os.path
import sys
import keyboard
import ctypes.wintypes
from getopt import getopt
def makefilename(base):
if base.lower().endswith(".png"):
suffix = ".png"
base = base[:-4]
elif base.lower().endswith(".jpg"):
suffix = ".jpg"
base = base[:-4]
else:
suffix = ".png"
for i in range(10000):
name = base + "%04d"%i + suffix
if not os.path.exists(name):
return name
raise Exception("Too many images of that name")
def windowSize(window):
rect = ctypes.wintypes.RECT()
ctypes.windll.dwmapi.DwmGetWindowAttribute(
window,
ctypes.wintypes.DWORD(9),
ctypes.byref(rect), ctypes.sizeof(rect))
return (rect.left,rect.top,rect.right,rect.bottom)
def processId(window):
pid = ctypes.wintypes.DWORD(0)
ctypes.windll.user32.GetWindowThreadProcessId(window, ctypes.byref(pid))
return pid.value
def activeAppArea():
pid = processId(ctypes.windll.user32.GetForegroundWindow())
EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
dimensions = [float("inf"),float("inf"),float("-inf"),float("-inf")]
def updateDimensions(window, param):
if processId(window)==pid and ctypes.windll.user32.IsWindowVisible(window):
size = windowSize(window)
dimensions[0] = min(dimensions[0], size[0])
dimensions[1] = min(dimensions[1], size[1])
dimensions[2] = max(dimensions[2], size[2])
dimensions[3] = max(dimensions[3], size[3])
return True
EnumWindows(EnumWindowsProc(updateDimensions), 0)
return dimensions
def grab(name, mode=None):
fname = makefilename(name)
print("Capturing to "+fname)
if mode is None:
area = activeAppArea()
elif mode == "full-screen":
area = None
else:
area = windowSize(ctypes.windll.user32.GetForegroundWindow())
PIL.ImageGrab.grab(bbox=area).save(makefilename(name))
if __name__ == '__main__':
mode = None
once = False
instant = False
opts,args = getopt(sys.argv[1:], "fw1i", ["full-screen", "window", "1", "instant"])
for o,a in opts:
if o in ("-f", "--full-screen"):
mode = "full-screen"
elif o in ("-w", "--window"):
mode = "window"
elif o in ("-1", "--1"):
once = True
elif o in ("-i", "--instant"):
instant = True
print("Capturing screen with 'Print Screen'. Press ctrl-c to exit.")
while True:
if not instant:
keyboard.wait("print screen")
grab(args[0] if args else "screenshot", mode=mode)
if once or instant:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment