Fastest Way to Take a Screenshot with Python on Windows

Fastest way to take a screenshot with python on windows

You could use win32 APIs directly .

  1. First give the focus to the App that you want to take screenshot of.
    link text

  2. Win32 API can help with the screenshot:

import win32gui
import win32ui
import win32con

w = 1920 # set this
h = 1080 # set this
bmpfilenamename = "out.bmp" #set this

hwnd = win32gui.FindWindow(None, windowname)
wDC = win32gui.GetWindowDC(hwnd)
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
cDC.BitBlt((0,0),(w, h) , dcObj, (0,0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, bmpfilenamename)

# Free Resources
win32gui.ReleaseDC(hwnd, wDC)

Python: Fastest way to take and save screenshots

Your first solution should be giving you more than one picture per second. The problem though is that you will be overwriting any pictures that occur within the same second, i.e. they will all have the same filename. To get around this you could create filenames that include 10ths of a second as follows:

from PIL import ImageGrab
from datetime import datetime

while True:
im = ImageGrab.grab()
dt =
fname = "pic_{}.{}.png".format(dt.strftime("%H%M_%S"), dt.microsecond // 100000), 'png')

On my machine, this gave the following output:


What is the most efficient way to capture screen in python using modules eg PIL or cv2? because It takes up a lot of ram

You can use mss which is an "An ultra fast cross-platform multiple screenshots module in pure python".

For example:

import time
import cv2
import numpy as np
from mss import mss

start_time = time.time()
mon = {'top': 200, 'left': 200, 'width': 200, 'height': 200}
with mss() as sct:
while True:
last_time = time.time()
img = sct.grab(mon)
print('The loop took: {0}'.format(time.time()-last_time))
cv2.imshow('test', np.array(img))
if cv2.waitKey(25) & 0xFF == ord('q'):


The loop took: 0.024120092391967773


Sample Image

The result is faster 100x than your current result.

Fast screenshot of a small part of the screen in Python

The Python mss module ( , ), an ultra fast cross-platform multiple screenshots module in pure Python using ctypes ( where MSS stands for Multiple Screen Shots ), is what you are looking for. The screenshots are fast enough to capture frames from a video and the smaller the part of the screen to grab the faster the capture (so there is apparently no cropping involved ). Check it out. mss.mss().grab() outperforms by far PIL.ImageGrab.grab(). Below a code example showing how to get the data of the screenshot pixels (allows to detect changes):

import mss
from time import perf_counter as T
left = 0
right = 2
top = 0
btm = 2

with mss.mss() as sct:
# parameter for sct.grab() can be:
monitor = sct.monitors[1] # entire screen
bbox = (left, top, right, btm) # screen part to capture

sct_im = sct.grab(bbox) # type: <class 'mss.screenshot.ScreenShot'>
eT=T();print(" >", eT-sT) # > 0.0003100260073551908

print(len(sct_im.raw), sct_im.raw)
# 16 bytearray(b'-12\xff\x02DU\xff-12\xff"S_\xff')

print(len(sct_im.rgb), sct_im.rgb)
# 12 b'21-UD\x0221-_S"'

Take screenshots **quickly** from python

If you want fast screenshots, you must use a lower level API, like DirectX or GTK. There are Python wrappers for those, like DirectPython and PyGTK. Some samples I've found follow:

  • PyGTK sample

  • Windows and DirectX samples

Related Topics

Leave a reply