Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Fastest way to take and save screenshots

I've been struggling to come up with a script that allows me to take screenshots of my desktop more than once per every second. I'm using Win10.

PIL:

from PIL import ImageGrab
import time

while True:
    im = ImageGrab.grab()
    fname = "dropfolder/%s.png" %int(time.time())
    im.save(fname,'PNG') 

Results 1.01 seconds per image.

PyScreeze (https://github.com/asweigart/pyscreeze):

import pyscreeze
import time

while True:
    fname = "dropfolder/%s.png" %int(time.time())
    x = pyscreeze.screenshot(fname)

Results 1.00 seconds per image.

Win32:

import win32gui
import win32ui 
import win32con
import time

w=1920 #res
h=1080 #res

while True:
    wDC = win32gui.GetWindowDC(0)
    dcObj=win32ui.CreateDCFromHandle(wDC)
    cDC=dcObj.CreateCompatibleDC()
    dataBitMap = win32ui.CreateBitmap()
    dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
    cDC.SelectObject(dataBitMap)
    cDC.BitBlt((0,0),(w, h) , dcObj, (0,0), win32con.SRCCOPY)
    fname = "dropfolder/%s.png" %int(time.time())
    dataBitMap.SaveBitmapFile(cDC, fname)
    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(0, wDC)
    win32gui.DeleteObject(dataBitMap.GetHandle())

Results 1.01 seconds per image.

Then I stumbled into thread (Fastest way to take a screenshot with python on windows) where it was suggested that gtk would yield phenomenal results.

However using gtk:

import gtk
import time

img_width = gtk.gdk.screen_width()
img_height = gtk.gdk.screen_height()

while True:
    screengrab = gtk.gdk.Pixbuf(
        gtk.gdk.COLORSPACE_RGB,
        False,
        8,
        img_width,
        img_height
    )

    fname = "dropfolder/%s.png" %int(time.time())
    screengrab.get_from_drawable(
        gtk.gdk.get_default_root_window(),
        gtk.gdk.colormap_get_system(),
        0, 0, 0, 0,
        img_width,
        img_height
        ).save(fname, 'png')

Results 2.34 seconds per image.

It seems to me like I'm doing something wrong, because people have been getting great results with gtk.

Any advices how to speed up the process?

Thanks!

like image 404
jjjayn Avatar asked Nov 01 '25 10:11

jjjayn


1 Answers

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 = datetime.now()
    fname = "pic_{}.{}.png".format(dt.strftime("%H%M_%S"), dt.microsecond // 100000)
    im.save(fname, 'png') 

On my machine, this gave the following output:

pic_1143_24.5.png
pic_1143_24.9.png
pic_1143_25.3.png
pic_1143_25.7.png
pic_1143_26.0.png
pic_1143_26.4.png
pic_1143_26.8.png
pic_1143_27.2.png
like image 154
Martin Evans Avatar answered Nov 03 '25 00:11

Martin Evans