Screenshots in record time - up to 2.5x faster than MSS (Multiple Screen Shots)
The module provides classes for capturing screenshots in Windows operating systems. It offers four different classes: ScreenshotOfRegion, ScreenshotOfOneMonitor, ScreenshotOfAllMonitors, and ScreenshotOfWindow. These classes allow you to capture screenshots of specific regions, individual monitors, all monitors, or specific windows (even background windows) on the screen.
For users who need to capture screenshots programmatically in their Python applications, this module can be of great interest. It provides a convenient and efficient way to capture screenshots using the Windows API, allowing for customization and flexibility in screenshot capturing.
One notable advantage of this module is its speed. It utilizes direct access to the Windows API and minimizes overhead, resulting in faster screenshot capturing compared to other libraries like MSS (Multiple Screen Shots). This can be beneficial for applications that require real-time or high-frequency screenshot capturing.
Furthermore, the module has minimal dependencies, making it lightweight and easy to integrate into existing projects. It relies on standard Windows libraries and ctypes for accessing the Windows API functions, reducing the need for additional external dependencies.
pip install fast-ctypes-screenshots
Tested against Windows 10 / Python 3.10 / Anaconda
How to use it
from time import time
import cv2
import numpy as np
from fast_ctypes_screenshots import (
ScreenshotOfRegion,
ScreenshotOfOneMonitor,
ScreenshotOfAllMonitors,
ScreenshotOfWindow,
)
# a simple benchmark function
def show_screenshot(
screenshotiter, stop_at_frame=100, quitkey="q", show_screenshot=True
):
def show_screenshotx():
cv2.imshow("test", screenshot)
if cv2.waitKey(1) & 0xFF == ord(quitkey):
cv2.destroyAllWindows()
return False
return True
framecounter = 0
fps = 0
start_time = time()
for screenshot in screenshotiter:
if stop_at_frame:
if framecounter > stop_at_frame:
break
framecounter += 1
if show_screenshot:
sho = show_screenshotx()
else:
sho = True
fps += 1
if not sho:
break
print(f"fast_ctypes_screenshots: {fps / (time() - start_time)}")
cv2.destroyAllWindows()
if __name__ == "__main__":
# Take one screenshot
# ScreenshotOfWindow works even with background windows
with ScreenshotOfWindow(
hwnd=920542, client=False, ascontiguousarray=False
) as screenshots_window:
img1 = screenshots_window.screenshot_window()
print(img1.shape)
with ScreenshotOfWindow(
hwnd=920542, client=True, ascontiguousarray=False
) as screenshots_window:
img2 = screenshots_window.screenshot_window()
print(img2.shape)
# Screenshot of all monitors
with ScreenshotOfAllMonitors(ascontiguousarray=False) as screenshots_all_monitor:
img4 = screenshots_all_monitor.screenshot_monitors()
print(img4.shape)
# Screenshot of one monitor, starting at 0
with ScreenshotOfOneMonitor(
monitor=0, ascontiguousarray=False
) as screenshots_monitor:
img5 = screenshots_monitor.screenshot_one_monitor()
print(img5.shape)
# x0=0, y0=40, x1=800, y1=680 -> rectangle
with ScreenshotOfRegion(
x0=0, y0=40, x1=800, y1=680, ascontiguousarray=False
) as screenshots_region:
img6 = screenshots_region.screenshot_region()
print(img6.shape)
#######################################################################
# Take many screenshots
# from a window
# screenshots_window is iterable
with ScreenshotOfWindow(
hwnd=920542, client=False, ascontiguousarray=False
) as screenshots_window:
show_screenshot(
screenshots_window, stop_at_frame=1500, quitkey="q", show_screenshot=True
)
with ScreenshotOfWindow(
hwnd=920542, client=True, ascontiguousarray=False
) as screenshots_window:
show_screenshot(
screenshots_window, stop_at_frame=1500, quitkey="q", show_screenshot=True
)
# from all monitors
# screenshots_all_monitor is iterable too
with ScreenshotOfAllMonitors(ascontiguousarray=False) as screenshots_all_monitor:
show_screenshot(
screenshots_all_monitor,
stop_at_frame=150,
quitkey="q",
show_screenshot=True,
)
# from one monitor
# screenshots_monitor is iterable as well
with ScreenshotOfOneMonitor(
monitor=0, ascontiguousarray=False
) as screenshots_monitor:
show_screenshot(
screenshots_monitor, stop_at_frame=150, quitkey="q", show_screenshot=True
)
with ScreenshotOfRegion(
x0=0, y0=40, x1=800, y1=680, ascontiguousarray=False
) as screenshots_region:
show_screenshot(
screenshots_region, stop_at_frame=150, quitkey="q", show_screenshot=True
)
Benchmark - MSS vs. fast-ctypes-screenshots
| Benchmark | FPS One Screen - with cv2.imshow - MSS | FPS One Screen - with cv2.imshow - fast_ctypes_screenshots | FPS One Screen - without cv2.imshow - MSS | FPS One Screen - without cv2.imshow - fast_ctypes_screenshots |
|---|---|---|---|---|
| 1 screen - 1920x1080 | 14.570637829934096 | 29.75346366655896 | 29.040460293245385 | 32.07449524721684 |
| 2 screens - 3840x1080 | 10.885839644361466 | 18.843871526097328 | 17.19836897143781 | 24.268109622214084 |
| region - 2800x960 | 13.54247110293269 | 28.722819983256283 | 21.342393892806598 | 29.528899151991656 |
# MSS https://python-mss.readthedocs.io/ vs. fast_ctypes_screenshots
# The code for the benchmark
import mss
print("\n\n-------------------------Benchmark - 1 screen - 1920x1080")
fps = 0
last_time = time()
with mss.mss() as sct:
for _ in range(150):
sct_img = sct.grab(sct.monitors[1])
img = np.array(sct_img)
cv2.imshow("test", img)
fps += 1
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
print(
f"\n\n\nFPS One Screen - with cv2.imshow - MSS: {fps / (time() - last_time)}\n"
)
print("FPS One Screen - with cv2.imshow - ", end=" ")
cv2.destroyAllWindows()
with ScreenshotOfOneMonitor(
monitor=0, ascontiguousarray=False
) as screenshots_monitor:
show_screenshot(
screenshots_monitor, stop_at_frame=150, quitkey="q", show_screenshot=True
)
cv2.destroyAllWindows()
#########################################################
fps = 0
last_time = time()
with mss.mss() as sct:
for _ in range(150):
sct_img = sct.grab(sct.monitors[1])
img = np.array(sct_img)
fps += 1
print(
f"\n\n\nFPS One Screen - without cv2.imshow - MSS: {fps / (time() - last_time)}\n"
)
print("FPS One Screen - without cv2.imshow - ", end=" ")
with ScreenshotOfOneMonitor(
monitor=0, ascontiguousarray=False
) as screenshots_monitor:
show_screenshot(
screenshots_monitor, stop_at_frame=150, quitkey="q", show_screenshot=False
)
cv2.destroyAllWindows()
#########################################################
print("\n\n-------------------------Benchmark - 2 screens - 3840x1080")
fps = 0
last_time = time()
with mss.mss() as sct:
for _ in range(100):
sct_img = sct.grab(sct.monitors[0])
img = np.array(sct_img)
cv2.imshow("test", img)
fps += 1
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
print(
f"\n\n\nFPS All screens - with cv2.imshow - MSS: {fps / (time() - last_time)}\n"
)
cv2.destroyAllWindows()
print("FPS All screens - with cv2.imshow - ", end=" ")
with ScreenshotOfAllMonitors(ascontiguousarray=False) as screenshots_region:
show_screenshot(
screenshots_region, stop_at_frame=100, quitkey="q", show_screenshot=True
)
cv2.destroyAllWindows()
#########################################################
fps = 0
last_time = time()
with mss.mss() as sct:
for _ in range(100):
sct_img = sct.grab(sct.monitors[0])
img = np.array(sct_img)
fps += 1
print(
f"\n\n\nFPS All screens - without cv2.imshow - MSS: {fps / (time() - last_time)}\n"
)
print("FPS All screens - without cv2.imshow - ", end=" ")
with ScreenshotOfAllMonitors(ascontiguousarray=False) as screenshots_region:
show_screenshot(
screenshots_region, stop_at_frame=100, quitkey="q", show_screenshot=False
)
#########################################################
print("\n\n-------------------------Benchmark - region - 2800x960")
fps = 0
last_time = time()
monitor = {"top": 40, "left": 0, "width": 2800, "height": 960}
with mss.mss() as sct:
for _ in range(150):
img = np.array(sct.grab(monitor))
cv2.imshow("test", img)
fps += 1
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
print(f"\n\n\nFPS Region - with cv2.imshow - MSS: {fps / (time() - last_time)}\n")
print("FPS Region - with cv2.imshow - ", end=" ")
cv2.destroyAllWindows()
with ScreenshotOfRegion(
x0=0, y0=40, x1=2800, y1=1000, ascontiguousarray=False
) as screenshots_region:
show_screenshot(
screenshots_region, stop_at_frame=150, quitkey="q", show_screenshot=True
)
cv2.destroyAllWindows()
#########################################################
fps = 0
last_time = time()
monitor = {"top": 40, "left": 0, "width": 2800, "height": 960}
with mss.mss() as sct:
for _ in range(150):
img = np.array(sct.grab(monitor))
fps += 1
print(
f"\n\n\nFPS Region - without cv2.imshow - MSS: {fps / (time() - last_time)}\n"
)
print("FPS Region - without cv2.imshow: ", end=" ")
with ScreenshotOfRegion(
x0=0, y0=40, x1=2800, y1=1000, ascontiguousarray=False
) as screenshots_region:
show_screenshot(
screenshots_region, stop_at_frame=150, quitkey="q", show_screenshot=False
)
Metadata
Release files for fast-ctypes-screenshots 0.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| fast_ctypes_screenshots-0.10.tar.gz | 27.2 kB | Without provenance | Details for fast_ctypes_screenshots-0.10.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| fast_ctypes_screenshots-0.10-py3-none-any.whl | Python 3 | none | any | Details for fast_ctypes_screenshots-0.10-py3-none-any.whl |
Total release size: 54.4 kB
Release files / fast_ctypes_screenshots-0.10.tar.gz
| Download URL | fast_ctypes_screenshots-0.10.tar.gz |
|---|---|
| Size | 27.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a965fa25411b61f68e86a2772cd98b50fb74958599458e710861c4cc88dd52ae
|
|
BLAKE2b-256 checksum How to use checksums |
76134027a4ac1c190025d948a39d908268e8764e2c649758241b2754bffcf5bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.10
|
Release files / fast_ctypes_screenshots-0.10-py3-none-any.whl
| Download URL | fast_ctypes_screenshots-0.10-py3-none-any.whl |
|---|---|
| Size | 27.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb7ee8c6ad7038c4429908dec470e1fffa831122d27d6d0362b2fda89b4a3f9d
|
|
BLAKE2b-256 checksum How to use checksums |
67ab7df625106bca97845bcf94e0338b80cfb0c777fe6e01ec311b42745d101c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.10
|
Security for fast-ctypes-screenshots 0.10
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.