tldr: Use Pillow
The pyscreenshot module is obsolete in most cases. It was created because PIL ImageGrab module worked on Windows only, but now Linux and macOS are also supported by Pillow. There are some features in pyscreenshot which can be useful in special cases: flexible backends, Wayland support, sometimes better performance, optional subprocessing.
The module can be used to copy the contents of the screen to a Pillow image memory using various back-ends. Replacement for the ImageGrab Module.
For handling image memory (e.g. saving to file, converting,..) please read Pillow documentation.
Links:
home: https://github.com/ponty/pyscreenshot
PYPI: https://pypi.python.org/pypi/pyscreenshot
Goal: Pyscreenshot tries to allow to take screenshots without installing 3rd party libraries. It is cross-platform. It is only a pure Python wrapper, a thin layer over existing back-ends. Its strategy should work on most Linux distributions: a lot of back-ends are wrapped, if at least one exists then it works, if not then one back-end should be installed.
Features:
Cross-platform wrapper
Capturing the whole desktop or an area
saving to Pillow image memory
some back-ends are based on this discussion: http://stackoverflow.com/questions/69645/take-a-screenshot-via-a-python-script-linux
pure Python library
supported Python versions: 3.6, 3.7, 3.8, 3.9
It has wrappers for various back-ends:
Quartz (Mac)
screencapture (Mac)
Old removed backends: QtPy, PyGTK
Performance is not the main target for this library, but you can benchmark the possible settings and choose the fastest one.
Interactivity is not supported.
Mouse pointer is not visible.
Known problems:
KDE Wayland has on screen notification
gnome-screenshot has Flash effect (https://bugzilla.gnome.org/show_bug.cgi?id=672759)
Installation:
$python3 -m pip install Pillow pyscreenshot
# pyscreenshot/examples/grabfullscreen.py"Grab the whole screen"importpyscreenshotasImageGrab# grab fullscreenim=ImageGrab.grab()# save image fileim.save("fullscreen.png")
# pyscreenshot/examples/grabbox.py"Grab the part of the screen"importpyscreenshotasImageGrab# part of the screenim=ImageGrab.grab(bbox=(10,10,510,510))# X1,Y1,X2,Y2# save image fileim.save("box.png")
# pyscreenshot/examples/virtdisp.py"Create screenshot of xmessage with Xvfb"fromtimeimportsleepfromeasyprocessimportEasyProcessfrompyvirtualdisplayimportDisplayimportpyscreenshotasImageGrabwithDisplay(size=(100,60))asdisp:# start Xvfb display# display is availablewithEasyProcess(["xmessage","hello"]):# start xmessagesleep(1)# wait for diplaying windowimg=ImageGrab.grab()img.save("xmessage.png")
Image:
The performance can be checked with pyscreenshot.check.speedtest module. Backends are started in a subprocess with default (safest) settings which is necessary to isolate them from the main process and from each other. Disabling this option makes performance much better, but it may cause problems in some cases.
Test on Ubuntu 20.04 X11
Versions:
$python3 -m pyscreenshot.check.versionspython 3.8.5pyscreenshot 2.3pil 8.0.1mss 6.1.0scrot 1.2grim ?.?maim 5.5.3imagemagick 6.9.10pyqt5 5.14.1pyqt pyside2 5.14.0pyside wx 4.0.7pygdk3 3.36.0mac_screencapture mac_quartz gnome_dbus ?.?gnome-screenshot 3.36.0kwin_dbus ?.?
$python3 -m pyscreenshot.check.speedtestn=10------------------------------------------------------default 1 sec ( 101 ms per call)pil 1.7 sec ( 166 ms per call)mss 1.9 sec ( 191 ms per call)scrot 0.97 sec ( 97 ms per call)grim maim 1.4 sec ( 144 ms per call)imagemagick 2.4 sec ( 235 ms per call)pyqt5 4.3 sec ( 429 ms per call)pyqt pyside2 4.2 sec ( 423 ms per call)pyside wx 4.1 sec ( 412 ms per call)pygdk3 2 sec ( 204 ms per call)mac_screencapture mac_quartz gnome_dbus 1.4 sec ( 144 ms per call)gnome-screenshot 3.8 sec ( 381 ms per call)kwin_dbus
$python3 -m pyscreenshot.check.speedtest --childprocess 0n=10------------------------------------------------------default 0.11 sec ( 10 ms per call)pil 0.09 sec ( 8 ms per call)mss 0.15 sec ( 15 ms per call)scrot 0.95 sec ( 95 ms per call)grim maim 1.5 sec ( 145 ms per call)imagemagick 2.4 sec ( 235 ms per call)pyqt5 1.1 sec ( 114 ms per call)pyqt pyside2 1.2 sec ( 118 ms per call)pyside wx 0.43 sec ( 43 ms per call)pygdk3 0.16 sec ( 15 ms per call)mac_screencapture mac_quartz gnome_dbus 1.5 sec ( 147 ms per call)gnome-screenshot 3.8 sec ( 383 ms per call)kwin_dbus
You can force a backend:
importpyscreenshotasImageGrabim=ImageGrab.grab(backend="scrot")
You can force if subprocess is applied, setting it to False together with mss gives the best performance in most cases:
# best performanceimportpyscreenshotasImageGrabim=ImageGrab.grab(backend="mss",childprocess=False)
Wayland is supported with two setups:
using D-Bus on GNOME or KDE. Python 3 only.
using Grim on any Wayland compositor with wlr-screencopy-unstable-v1 support. (GNOME:no, KDE:no, Sway:yes)
If both Wayland and X are available then Wayland is preferred because Xwayland can not be used for screenshot.
Rules for decision:
use X if DISPLAY variable exists and XDG_SESSION_TYPE variable != "wayland"
use Wayland if 1. is not successful
Only pure python modules are used:
EasyProcess for calling programs
entrypoint2 for generating command line interface
MSS backend is added because it is very fast and pure and multiplatform
jeepney for D-Bus calls