Usage#

Import#

MSS can be used simply as:

from mss import MSS

with MSS() as sct:
    # ...

For compatibility with existing code, mss.mss() is still available in 11.0, but deprecated:

import mss

with mss.mss() as sct:  # Deprecated in 10.2
    # ...

For compatibility with existing code, platform-specific class names are also still available in 11.0, but are also deprecated:

# GNU/Linux
from mss.linux import MSS

# macOS
from mss.darwin import MSS

# Microsoft Windows
from mss.windows import MSS

Capturing Screenshots#

If you simply need to capture one or more monitors to PNG files, the Examples section has code ready for you to copy and paste.

If instead you want to use the pixel data yourself, you can do so easily, with the mss.MSS.grab() method.

You’ll first need to decide whether you want to capture all the monitors, a single monitor, or a specific region of the screen.

For capturing one or more monitors, the mss.MSS object has a mss.MSS.monitors attribute that is a list of all the monitors, starting from index 1, as well as the full virtual screen (all monitors combined) at index 0. The primary monitor, the one that holds the taskbar or similar system UI, is available as mss.MSS.primary_monitor.

For capturing a specific region, you can pass mss.MSS.grab() a dictionary with the keys top, left, width, and height. For instance, to capture a 100x100 pixel region starting at the top-left corner of the screen, you could use {"top": 0, "left": 0, "width": 100, "height": 100}. You can also use a PIL-style box, which is a 4-tuple of (left, top, right, bottom).

Once you’ve decided what you want to capture, you can call mss.MSS.grab() with the appropriate monitor or region. This will return a mss.ScreenShot object, which contains the pixel data and other information about the screenshot.

For instance, you can capture the first monitor and get a mss.ScreenShot object like this:

with MSS() as sct:
    sct_img = sct.grab(sct.primary_monitor)

Ok, now you’ve got the mss.ScreenShot object. But what do you do with it?

Accessing Pixel Data#

Once you have the mss.ScreenShot object, you’ll want to use the pixel data. There are several ways, depending on what you want to do with it. This is a quick overview of the options, with more details in the linked references.

If you want to examine individual pixels, you can get them from the mss.ScreenShot object directly, using any of several methods:

Often, though, you’ll export screenshot data to a different framework. You can often do this by passing the mss.ScreenShot.bgra data to the framework’s appropriate function. MSS also provides easy-to-use methods to work with many popular frameworks:

NumPy Array Interface Protocol#

Many libraries support the NumPy array interface protocol . This allows them to accept a mss.ScreenShot object directly to these libraries, without needing to convert it to a NumPy array first. Some examples include the following libraries:

  • Many SciPy projects

  • CuPy , a GPU-accelerated NumPy-like library

  • JAX , a high-performance machine learning library

  • Pandas , a popular data analysis library

  • scikit-learn , a popular machine learning library

  • Matplotlib , a popular plotting library

  • Some functions from OpenCV , a popular computer vision library

When using the NumPy array interface protocol, the returned object is in HWC (height, width, channels) format, with the channels in BGRA order, and with a data type of numpy.uint8 .

Note that most libraries do not expect the alpha channel to be present, or expect an order other than the BGRA order used in this automatic conversion. You may prefer to use the mss.ScreenShot.to_numpy() method instead, since it can return the pixel data in most common layouts, orders, and data types.

Alpha Channel#

The alpha channel is used for transparency in images. However, it’s also sometimes just used as a placeholder for an unused channel. In the case of screenshots, the alpha channel is often not used for transparency, and may be filled with zeros. If an image processing library interprets the alpha channel as transparency, this can make it think the image is transparent.

For instance, if you use Matplotlib to display a screenshot, you might see nothing at all. This happens if the OS has filled the alpha channel with zeros (which is common on many platforms).

The methods described above, such as mss.ScreenShot.to_numpy(), can convert the pixel data to BGR (or RGB) format, removing the alpha channel entirely.

In other words, instead of plt.imshow(img), you can use plt.imshow(img.to_numpy(channels="RGB")) to display the screenshot correctly.

In the future, MSS may provide an indicator of whether the alpha channel is meaningful or not, as well as whether it is premultiplied or straight alpha. For now, you should assume that the alpha channel is not meaningful, and either ignore or remove it, unless you know that it’s meaningful for your specific circumstances.

Memory Sharing#

There’s a subtlety to be aware of in the following conditions:

  1. You are using any of the above methods (or properties, or the NumPy array interface protocol) to convert a mss.ScreenShot object to another format, and

  2. You use two different methods, or the same method twice, on the same mss.ScreenShot object, and

  3. You modify the pixel data of the returned object (e.g., a NumPy array or a PIL image).

When using any of the above methods, the returned object might (but does not always) share pixel memory with the original mss.ScreenShot object. This means that if you modify the returned object’s pixels, it may also modify the pixels stored in the original mss.ScreenShot object, or other objects that share the same memory.

For instance, if you use mss.ScreenShot.to_numpy() to create a NumPy array, then use mss.ScreenShot.to_pil() to create a PIL image, both objects may share the same memory. If you modify the pixels of the NumPy array, it may also modify the pixels of the PIL image, and vice versa.

Pixel memory is never guaranteed to be shared; it depends on many specifics. Whether memory is shared or not is an implementation detail, and not part of the semantic versioning guarantees of MSS: it may change in future versions, or even when a program is run in different environments.

If you want to ensure that memory is not shared, you can make a copy of the returned object. For instance, if you want to ensure that a NumPy array does not share memory with the original mss.ScreenShot object, you can use the numpy.ndarray.copy() method to create a copy of the array.

Intensive Use#

If you plan to integrate MSS inside your own module or software, pay attention to using it wisely.

This is a bad usage:

for _ in range(100):
    with MSS() as sct:
        sct.shot()

This is a much better usage, memory efficient:

with MSS() as sct:
    for _ in range(100):
        sct.shot()

Also, it is a good thing to save the MSS instance inside an attribute of your class and calling it when needed.

Direct Screenshot Buffers#

On supported platforms, MSS can expose screenshot data directly from operating system buffers instead of copying it into a separate Python-owned buffer. This reduces memory copying and can improve performance when processing screenshots with libraries that support the Python buffer protocol, such as NumPy and OpenCV.

This optimization is enabled automatically and does not require any changes to application code.

Requirements:

  • Python 3.12 or later

  • GNU/Linux

Support for additional operating systems is planned.

Multithreading#

MSS is thread-safe and can be used from multiple threads.

Sharing one MSS object: You can use the same MSS object from multiple threads. Calls to mss.MSS.grab() (and other capture methods) are serialized automatically, meaning only one thread will capture at a time. This may be relaxed in a future version if it can be done safely.

Using separate MSS objects: You can also create different MSS objects in different threads. Whether these run concurrently or are serialized by the OS depends on the platform.

Custom mss.screenshot.ScreenShot classes (see Custom ScreenShot Subclass) must not call mss.MSS.grab() in their constructor.

Danger

These guarantees do not apply to the obsolete Xlib backend. That backend is only used if you specifically request it, so you won’t be caught off-guard.

Added in version 10.2.0: Prior to this version, on some operating systems, the MSS object could only be used on the thread on which it was created.

Backends#

Some platforms have multiple ways to take screenshots. In MSS, these are known as backends. The mss.MSS constructor will normally autodetect which one is appropriate for your situation, but you can override this if you want. For instance, you may know that your specific situation requires a particular backend.

If you want to choose a particular backend, you can pass the backend keyword to mss.MSS:

with MSS(backend="xgetimage") as sct:
    ...

GNU/Linux has multiple backend implementations. Windows also exposes the named gdi backend, which is currently the same as default. The GNU/Linux backends are described in their own section below.

GNU/Linux#

Display#

On GNU/Linux, the default display is taken from the DISPLAY environment variable. You can instead specify which display to use (useful for distant screenshots via SSH) using the display keyword:

import mss

with mss.MSS(display=":0.0") as sct:
    for filename in sct.save():
        print(filename)

Backends#

The GNU/Linux implementation has multiple backends (see Backends), or ways it can take screenshots. The mss.MSS constructor will normally autodetect which one is appropriate, but you can override this if you want.

There are three available backends.

xshmgetimage (default)

The fastest backend, based on xcb_shm_get_image(). It is roughly three times faster than xgetimage and is used automatically. When the MIT-SHM extension is unavailable (for example on remote SSH displays), it transparently falls back to xgetimage so you can always request it safely.

xgetimage

A highly-compatible, but slower, backend based on xcb_get_image(). Use this explicitly only when you know that xshmgetimage cannot operate in your environment.

xlib

The legacy backend powered by XGetImage(). It is kept solely for systems where XCB libraries are unavailable and no new features are being added to it.

Command Line#

You can use mss via the CLI:

mss --help

Or via direct call from Python:

$ python -m mss --help
usage: mss [-h] [-c COORDINATES] [-l {0,1,2,3,4,5,6,7,8,9}] [-m MONITOR]
       [-o OUTPUT] [--with-cursor] [-q] [-b BACKEND] [-v]

options:
-h, --help            show this help message and exit
-c COORDINATES, --coordinates COORDINATES
                      the part of the screen to capture: top, left, width, height
-l {0,1,2,3,4,5,6,7,8,9}, --level {0,1,2,3,4,5,6,7,8,9}
                      the PNG compression level
-m MONITOR, --monitor MONITOR
                      the monitor to screenshot
-o OUTPUT, --output OUTPUT
                      the output file name
-b, --backend BACKEND
                      platform-specific backend to use
                      (Linux: default/xlib/xgetimage/xshmgetimage; macOS: default; Windows: default/gdi)
--with-cursor         include the cursor
-q, --quiet           do not print created files
-v, --version         show program's version number and exit

Added in version 3.1.1.

Added in version 8.0.0: --with-cursor to include the cursor in screenshots.

Added in version 10.2.0: --backend to force selecting the backend to use.