A Python high-performance screenshot library for Windows using Desktop Duplication API
Project description
DXcam
Fast Python Screen Capture for Windows - Updated 2026
import dxcam
with dxcam.create() as camera:
frame = camera.grab()
Live API Docs: https://ra1nty.github.io/DXcam/
Introduction
DXcam is a high-performance python screenshot and capture library for Windows based on the Desktop Duplication API. It is designed for low-latency, high-FPS capture pipelines (including full-screen Direct3D applications).
Compared with common Python alternatives, DXcam focuses on:
- Higher capture throughput (240+fps on 1080p)
- Stable capture for full-screen exclusive Direct3D apps
- Better FPS pacing for continuous video capture
- Support DXGI / Windows Graphics Capture dual backend
- Seamless integration for AI Agent / Computer Vision use cases.
Installation
From PyPI (pip)
Minimal install:
pip install dxcam
Full feature: (includes OpenCV-based color conversion, WinRT capture backend support:):
pip install "dxcam[cv2,winrt]"
Notes:
- Official Windows wheels are built for CPython
3.10to3.14. - Binary wheels include the Cython kernels used by processor backends.
From source
Please refer to CONTRIBUTING.
Contributing / Dev
Contributions are welcome! Development setup and contributor workflow are documented in CONTRIBUTING.md.
Usage
Each output (monitor) is associated with one DXCamera instance.
import dxcam
camera = dxcam.create() # primary output on device 0
To specify backends:
camera = dxcam.create(
backend="dxgi", # default Desktop Duplication backend
processor_backend="cv2" # default OpenCV processor
)
Screenshot
frame = camera.grab()
grab() returns a numpy.ndarray. None if no new frame is available since the last capture (for backward compatibility); use camera.grab(new_frame_only=False) to make dxcam always return the latest frame.
Use copy=False (or camera.grab_view()) for a zero-copy view. This is faster, but the returned buffer can be overwritten by later captures.
To capture a region:
left, top = (1920 - 640) // 2, (1080 - 640) // 2
right, bottom = left + 640, top + 640
frame = camera.grab(region=(left, top, right, bottom)) # numpy.ndarray of size (640x640x3) -> (HXWXC)
Screen Capture
camera.start(region=(left, top, right, bottom), target_fps=60)
camera.is_capturing # True
# ...
camera.stop()
camera.is_capturing # False
Consume the Screen Capture Data
for _ in range(1000):
frame = camera.get_latest_frame() # blocks until a frame is available
The screen capture mode spins up a thread that polls newly rendered frames and stores them in an in-memory ring buffer. The blocking and
video_modebehavior is designed for downstream video recording and machine learning workloads.
Useful variants:
camera.get_latest_frame(with_timestamp=True)->(frame, frame_timestamp)-> return frame timestampcamera.get_latest_frame_view()-> zero-copy view into the frame buffercamera.grab(copy=False)/camera.grab_view()-> zero-copy latest-frame snapshot
When
start()capture is running, callinggrab()reads from the in-memory ring buffer instead of directly polling DXGI.
Safely Releasing Resources
release() stops capture, frees buffers, and releases capture resources.
After release(), the same instance cannot be reused.
camera = dxcam.create(output_idx=0, output_color="BGR")
camera.release()
# camera.start() # raises RuntimeError
Equivalently you can use context manager:
with dxcam.create() as camera:
frame = camera.grab()
# resource released automatically
Full API Docs: https://ra1nty.github.io/DXcam/
Advanced Usage and Remarks
Multiple monitors / GPUs
cam1 = dxcam.create(device_idx=0, output_idx=0)
cam2 = dxcam.create(device_idx=0, output_idx=1)
cam3 = dxcam.create(device_idx=1, output_idx=1)
img1 = cam1.grab()
img2 = cam2.grab()
img3 = cam3.grab()
Inspect available devices/outputs:
>>> import dxcam
>>> print(dxcam.device_info())
'Device[0]:<Device Name:NVIDIA GeForce RTX 3090 Dedicated VRAM:24348Mb VendorId:4318>\n'
>>> print(dxcam.output_info())
'Device[0] Output[0]: Res:(1920, 1080) Rot:0 Primary:True\nDevice[0] Output[1]: Res:(1920, 1080) Rot:0 Primary:False\n'
Output Format
Set output color mode when creating the camera:
dxcam.create(output_color="BGRA")
Supported modes: "RGB", "RGBA", "BGR", "BGRA", "GRAY".
Notes:
- Data is returned as
numpy.ndarray. BGRAdoes not require OpenCV and is the leanest dependency path.RGB,BGR,RGBA,GRAYrequire conversion (cv2or compilednumpybackend).
Frame Buffer
DXcam uses a fixed-size ring buffer in-memory. New frames overwrite old frames when full.
camera = dxcam.create(max_buffer_len=120) # default is 8
Target FPS
DXcam uses high-resolution pacing with drift correction to run near target_fps.
camera.start(target_fps=120) # default to 60, greater than 120 is resource heavy
On Python 3.11+, DXcam relies on Windows high-resolution timer behavior used by time.sleep().
On older versions, DXcam uses WinAPI waitable timers directly.
Frame Timestamp
Read the most recent frame timestamp (seconds):
camera.start(target_fps=60)
frame, ts = camera.get_latest_frame(with_timestamp=True)
camera.stop()
For backend="dxgi", this value comes from DXGI_OUTDUPL_FRAME_INFO.LastPresentTime.
For backend="winrt", this value is derived from WinRT SystemRelativeTime.
Video Mode
With video_mode=True, DXcam fills the buffer at target FPS, reusing the previous frame if needed, even if no new frame is rendered.
import cv2
import dxcam
target_fps = 30
camera = dxcam.create(output_color="BGR")
camera.start(target_fps=target_fps, video_mode=True)
writer = cv2.VideoWriter(
"video.mp4", cv2.VideoWriter_fourcc(*"mp4v"), target_fps, (1920, 1080)
)
for _ in range(600):
writer.write(camera.get_latest_frame())
camera.stop()
writer.release()
Capture Backend
DXcam supports two capture backends:
dxgi(default): Desktop Duplication API path with broad compatibility.winrt: Windows Graphics Capture path.
Use it like this:
camera = dxcam.create(backend="dxgi")
camera = dxcam.create(backend="winrt")
Guideline:
- If you need cursor rendering, use
winrt. - Start with
dxgifor most workloads, especially one-shot grab. - Try
winrtif it performs better on your machine or fits your app constraints.
Processor Backend
DXcam capture backends (dxgi/winrt) first acquire a BGRA frame.
The processor backend then handles post-processing:
- optional rotation/cropping preparation
- color conversion to your
output_color
Recommended backend choice:
- OpenCV installed: use
cv2(default) - No OpenCV installed: use
numpy(Cython kernels)
Use it like this:
camera = dxcam.create(processor_backend="cv2")
camera = dxcam.create(processor_backend="numpy")
Official Windows wheels already include the compiled NumPy kernels.
Only for source installs:
set DXCAM_BUILD_CYTHON=1
pip install -e .[cython] --no-build-isolation
If processor_backend="numpy" is selected but compiled kernels are unavailable,
DXcam logs a warning and falls back to cv2 behavior. In that fallback path,
install OpenCV for non-BGRA output modes.
Benchmarks
When using a similar logic (only capture newly rendered frames) running on a 240fps output, DXCam, python-mss, D3DShot benchmarked as follow:
| DXcam | python-mss | D3DShot | |
|---|---|---|---|
| Average FPS | 239.19 :checkered_flag: | 75.87 | 118.36 |
| Std Dev | 1.25 | 0.5447 | 0.3224 |
The benchmark is across 5 runs, with a light-moderate usage on my PC (5900X + 3090; Chrome ~30tabs, VS Code opened, etc.), I used the Blur Buster UFO test to constantly render 240 fps on my monitor. DXcam captured almost every frame rendered. You will see some benchmarks online claiming 1000+fps capture while most of them is busy-spinning a for loop on a staled frame (no new frame rendered on screen in test scenario).
For Targeting FPS:
| (Target)\(mean,std) | DXcam | python-mss | D3DShot |
|---|---|---|---|
| 60fps | 61.71, 0.26 :checkered_flag: | N/A | 47.11, 1.33 |
| 30fps | 30.08, 0.02 :checkered_flag: | N/A | 21.24, 0.17 |
Work Referenced
OBS Studio - implementation ideas and references.
D3DShot : DXcam borrowed some ctypes header from the no-longer maintained D3DShot.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dxcam-0.3.0.tar.gz.
File metadata
- Download URL: dxcam-0.3.0.tar.gz
- Upload date:
- Size: 48.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d524da45adf70e044865e7d4e9098e655d6734951781155dda50c1292e20d8bd
|
|
| MD5 |
03596e168da10022ef71c22b92cf95a9
|
|
| BLAKE2b-256 |
deb7b3d3e3fa42f347ac4b37fd639634935b4eefff1d5d61bdf72a6d8b906919
|
Provenance
The following attestation bundles were made for dxcam-0.3.0.tar.gz:
Publisher:
release.yml on ra1nty/DXcam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dxcam-0.3.0.tar.gz -
Subject digest:
d524da45adf70e044865e7d4e9098e655d6734951781155dda50c1292e20d8bd - Sigstore transparency entry: 1088835880
- Sigstore integration time:
-
Permalink:
ra1nty/DXcam@de356cb5a39f50645d495c522fabb03e984728e7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/ra1nty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@de356cb5a39f50645d495c522fabb03e984728e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dxcam-0.3.0-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: dxcam-0.3.0-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 339.5 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f08a8505b4ea0afbf1ad9f741c512030ef9119dd029f65a08a0e635f616113e0
|
|
| MD5 |
d62bbdaa7e8ab3f346f591a9ad1fd9c9
|
|
| BLAKE2b-256 |
bea0ef29032254cfb88d0ad595579c1cc9912dbd0d0ca8a525e0a235e87f5098
|
Provenance
The following attestation bundles were made for dxcam-0.3.0-cp314-cp314-win_amd64.whl:
Publisher:
release.yml on ra1nty/DXcam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dxcam-0.3.0-cp314-cp314-win_amd64.whl -
Subject digest:
f08a8505b4ea0afbf1ad9f741c512030ef9119dd029f65a08a0e635f616113e0 - Sigstore transparency entry: 1088836046
- Sigstore integration time:
-
Permalink:
ra1nty/DXcam@de356cb5a39f50645d495c522fabb03e984728e7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/ra1nty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@de356cb5a39f50645d495c522fabb03e984728e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dxcam-0.3.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: dxcam-0.3.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 339.2 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3de4d64e6d85a4c3c5b869dd35eba82d4784e5b6c4b1703e0cb09da14be9575
|
|
| MD5 |
02b7b5acb4221693c683597724b7ac4b
|
|
| BLAKE2b-256 |
32a0f4c321b068cc1eb20aa56cd531c5cb449370d77b115075d9828853da8a05
|
Provenance
The following attestation bundles were made for dxcam-0.3.0-cp313-cp313-win_amd64.whl:
Publisher:
release.yml on ra1nty/DXcam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dxcam-0.3.0-cp313-cp313-win_amd64.whl -
Subject digest:
d3de4d64e6d85a4c3c5b869dd35eba82d4784e5b6c4b1703e0cb09da14be9575 - Sigstore transparency entry: 1088836117
- Sigstore integration time:
-
Permalink:
ra1nty/DXcam@de356cb5a39f50645d495c522fabb03e984728e7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/ra1nty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@de356cb5a39f50645d495c522fabb03e984728e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dxcam-0.3.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: dxcam-0.3.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 339.4 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab75b16529b8bd7337dfcb663525c338233a24b4c5b76193ced82a70e16edf49
|
|
| MD5 |
60c771d74c1799ccd0d20bc6bccbac55
|
|
| BLAKE2b-256 |
323c6aca1d8a906ccb5d7b5993b99822dbd60ac18470e88eee845afd927d678f
|
Provenance
The following attestation bundles were made for dxcam-0.3.0-cp312-cp312-win_amd64.whl:
Publisher:
release.yml on ra1nty/DXcam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dxcam-0.3.0-cp312-cp312-win_amd64.whl -
Subject digest:
ab75b16529b8bd7337dfcb663525c338233a24b4c5b76193ced82a70e16edf49 - Sigstore transparency entry: 1088835936
- Sigstore integration time:
-
Permalink:
ra1nty/DXcam@de356cb5a39f50645d495c522fabb03e984728e7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/ra1nty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@de356cb5a39f50645d495c522fabb03e984728e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dxcam-0.3.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: dxcam-0.3.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 338.9 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
499aba3283349a19d09db67e98547c8cb686470491f0127463072bc45cf3d611
|
|
| MD5 |
6b67a96e060f87bad617e93cf710de1b
|
|
| BLAKE2b-256 |
07506eaa432be12554dfc44fde995134fda64c1bf7a58c3ae9555b411b2faf92
|
Provenance
The following attestation bundles were made for dxcam-0.3.0-cp311-cp311-win_amd64.whl:
Publisher:
release.yml on ra1nty/DXcam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dxcam-0.3.0-cp311-cp311-win_amd64.whl -
Subject digest:
499aba3283349a19d09db67e98547c8cb686470491f0127463072bc45cf3d611 - Sigstore transparency entry: 1088836169
- Sigstore integration time:
-
Permalink:
ra1nty/DXcam@de356cb5a39f50645d495c522fabb03e984728e7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/ra1nty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@de356cb5a39f50645d495c522fabb03e984728e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dxcam-0.3.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: dxcam-0.3.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 339.4 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44024a1d4183b8ce402be2fef1723de41821d89eabb956df0c871e2943d23d40
|
|
| MD5 |
210a6ed07904a72bd98a15b4965bc315
|
|
| BLAKE2b-256 |
9342075c52069750e052f9c529442b771761e96da48b7c34d90cb72cdf97379b
|
Provenance
The following attestation bundles were made for dxcam-0.3.0-cp310-cp310-win_amd64.whl:
Publisher:
release.yml on ra1nty/DXcam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dxcam-0.3.0-cp310-cp310-win_amd64.whl -
Subject digest:
44024a1d4183b8ce402be2fef1723de41821d89eabb956df0c871e2943d23d40 - Sigstore transparency entry: 1088835993
- Sigstore integration time:
-
Permalink:
ra1nty/DXcam@de356cb5a39f50645d495c522fabb03e984728e7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/ra1nty
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@de356cb5a39f50645d495c522fabb03e984728e7 -
Trigger Event:
push
-
Statement type: