dxcam 0.1.0.dev1__tar.gz → 0.2.0.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/LICENSE +21 -21
- dxcam-0.2.0.dev1/MANIFEST.in +1 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/PKG-INFO +334 -234
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/README.md +289 -203
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/__init__.py +288 -197
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/_libs/d3d11.py +280 -270
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/_libs/dxgi.py +267 -256
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/_libs/user32.py +28 -28
- dxcam-0.2.0.dev1/dxcam/core/__init__.py +10 -0
- dxcam-0.2.0.dev1/dxcam/core/backend.py +49 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/core/device.py +100 -100
- dxcam-0.2.0.dev1/dxcam/core/duplicator.py +22 -0
- dxcam-0.1.0.dev1/dxcam/core/duplicator.py → dxcam-0.2.0.dev1/dxcam/core/dxgi_duplicator.py +223 -219
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/core/output.py +69 -69
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/core/stagesurf.py +94 -94
- dxcam-0.2.0.dev1/dxcam/core/winrt_duplicator.py +549 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/dxcam.py +854 -602
- dxcam-0.2.0.dev1/dxcam/processor/__init__.py +7 -0
- dxcam-0.2.0.dev1/dxcam/processor/_numpy_kernels.c +39123 -0
- dxcam-0.2.0.dev1/dxcam/processor/_numpy_kernels.pyx +725 -0
- dxcam-0.2.0.dev1/dxcam/processor/base.py +90 -0
- dxcam-0.2.0.dev1/dxcam/processor/cv2_processor.py +356 -0
- dxcam-0.2.0.dev1/dxcam/processor/numpy_processor.py +128 -0
- dxcam-0.2.0.dev1/dxcam/types.py +47 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/util/io.py +96 -96
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/util/timer.py +119 -115
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam.egg-info/PKG-INFO +334 -234
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam.egg-info/SOURCES.txt +10 -1
- dxcam-0.2.0.dev1/dxcam.egg-info/requires.txt +19 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/pyproject.toml +89 -61
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/setup.cfg +4 -4
- dxcam-0.2.0.dev1/setup.py +46 -0
- dxcam-0.2.0.dev1/tests/test_bgra_conversion_parity.py +88 -0
- dxcam-0.1.0.dev1/dxcam/core/__init__.py +0 -7
- dxcam-0.1.0.dev1/dxcam/processor/__init__.py +0 -1
- dxcam-0.1.0.dev1/dxcam/processor/base.py +0 -53
- dxcam-0.1.0.dev1/dxcam/processor/numpy_processor.py +0 -171
- dxcam-0.1.0.dev1/dxcam/types.py +0 -10
- dxcam-0.1.0.dev1/dxcam.egg-info/requires.txt +0 -5
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/_libs/__init__.py +0 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam/util/__init__.py +0 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam.egg-info/dependency_links.txt +0 -0
- {dxcam-0.1.0.dev1 → dxcam-0.2.0.dev1}/dxcam.egg-info/top_level.txt +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 Rain
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Rain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include dxcam/processor *.pyx
|
|
@@ -1,234 +1,334 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: dxcam
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A Python high-performance screenshot library for Windows using Desktop Duplication API
|
|
5
|
-
Author: ra1nty
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Source, https://github.com/ra1nty/DXcam
|
|
8
|
-
Project-URL: Tracker, https://github.com/ra1nty/DXcam/issues
|
|
9
|
-
Keywords: screen,screenshot,screencapture,screengrab,windows
|
|
10
|
-
Classifier: Development Status ::
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.
|
|
17
|
-
Classifier:
|
|
18
|
-
Classifier:
|
|
19
|
-
Classifier: Operating System :: Microsoft :: Windows
|
|
20
|
-
Classifier:
|
|
21
|
-
Classifier:
|
|
22
|
-
Classifier: Topic :: Multimedia :: Graphics
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
camera.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
```python
|
|
208
|
-
camera = dxcam.create(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dxcam
|
|
3
|
+
Version: 0.2.0.dev1
|
|
4
|
+
Summary: A Python high-performance screenshot library for Windows using Desktop Duplication API
|
|
5
|
+
Author: ra1nty
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Source, https://github.com/ra1nty/DXcam
|
|
8
|
+
Project-URL: Tracker, https://github.com/ra1nty/DXcam/issues
|
|
9
|
+
Keywords: screen,screenshot,screencapture,screengrab,windows
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
20
|
+
Classifier: Operating System :: Microsoft :: Windows :: Windows 10
|
|
21
|
+
Classifier: Operating System :: Microsoft :: Windows :: Windows 11
|
|
22
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
23
|
+
Classifier: Topic :: Multimedia :: Graphics :: Capture
|
|
24
|
+
Classifier: Topic :: Multimedia :: Graphics :: Capture :: Screen Capture
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: comtypes
|
|
29
|
+
Requires-Dist: numpy
|
|
30
|
+
Provides-Extra: cv2
|
|
31
|
+
Requires-Dist: opencv-python; extra == "cv2"
|
|
32
|
+
Provides-Extra: cython
|
|
33
|
+
Requires-Dist: Cython==3.1.1; extra == "cython"
|
|
34
|
+
Provides-Extra: winrt
|
|
35
|
+
Requires-Dist: winrt-runtime>=3.2.1; extra == "winrt"
|
|
36
|
+
Requires-Dist: winrt-Windows.Foundation>=3.2.1; extra == "winrt"
|
|
37
|
+
Requires-Dist: winrt-Windows.Foundation.Collections>=3.2.1; extra == "winrt"
|
|
38
|
+
Requires-Dist: winrt-Windows.Graphics>=3.2.1; extra == "winrt"
|
|
39
|
+
Requires-Dist: winrt-Windows.Graphics.Capture>=3.2.1; extra == "winrt"
|
|
40
|
+
Requires-Dist: winrt-Windows.Graphics.Capture.Interop>=3.2.1; extra == "winrt"
|
|
41
|
+
Requires-Dist: winrt-Windows.Graphics.DirectX>=3.2.1; extra == "winrt"
|
|
42
|
+
Requires-Dist: winrt-Windows.Graphics.DirectX.Direct3D11>=3.2.1; extra == "winrt"
|
|
43
|
+
Requires-Dist: winrt-Windows.Graphics.DirectX.Direct3D11.Interop>=3.2.1; extra == "winrt"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# **DXcam**
|
|
47
|
+
> ***Fast Python Screen Capture for Windows - Updated 2026***
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import dxcam
|
|
51
|
+
|
|
52
|
+
camera = dxcam.create()
|
|
53
|
+
frame = camera.grab()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Introduction
|
|
57
|
+
DXcam is a high-performance python screenshot and capture library for Windows based on the Desktop Duplication API.
|
|
58
|
+
It is designed for low-latency, high-FPS capture pipelines (including full-screen Direct3D applications).
|
|
59
|
+
|
|
60
|
+
Compared with common Python alternatives, DXcam focuses on:
|
|
61
|
+
- Higher capture throughput
|
|
62
|
+
- Stable capture for full-screen exclusive Direct3D apps
|
|
63
|
+
- Correct handling of scaled/stretched outputs
|
|
64
|
+
- Better FPS pacing for continuous/video capture
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
### From PyPI (pip)
|
|
68
|
+
Minimal install:
|
|
69
|
+
```bash
|
|
70
|
+
pip install dxcam
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Full feature: (includes OpenCV-based color conversion, WinRT capture backend support:):
|
|
74
|
+
```bash
|
|
75
|
+
pip install "dxcam[cv2,winrt]"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Notes:
|
|
79
|
+
- Official Windows wheels are built for CPython `3.10` to `3.14`.
|
|
80
|
+
- Binary wheels include the Cython kernels used by processor backends.
|
|
81
|
+
|
|
82
|
+
### From source (uv)
|
|
83
|
+
```bash
|
|
84
|
+
uv sync
|
|
85
|
+
# include OpenCV conversion backend
|
|
86
|
+
uv sync --extra cv2
|
|
87
|
+
# include optional Cython tooling
|
|
88
|
+
uv sync --extra cython
|
|
89
|
+
# include WinRT backend
|
|
90
|
+
uv sync --extra winrt
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Build local Cython kernels from source:
|
|
94
|
+
```bash
|
|
95
|
+
set DXCAM_BUILD_CYTHON=1
|
|
96
|
+
uv pip install -e .[cython] --no-build-isolation
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Dev environment (uv + ruff + ty)
|
|
100
|
+
```bash
|
|
101
|
+
uv venv --python 3.11 .venv
|
|
102
|
+
uv sync --dev
|
|
103
|
+
uv run ruff check dxcam
|
|
104
|
+
uv run ty check dxcam
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### API docs (pdoc)
|
|
108
|
+
Generate autodocs for the public API surface:
|
|
109
|
+
```bash
|
|
110
|
+
uv run pdoc -d google -o site dxcam dxcam.dxcam dxcam.types
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Preview locally by opening `site/index.html`.
|
|
114
|
+
CI builds docs on pull requests, and docs are deployed from `main` via GitHub Pages.
|
|
115
|
+
|
|
116
|
+
## Usage
|
|
117
|
+
Each output (monitor) is associated with one `DXCamera` instance.
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import dxcam
|
|
121
|
+
camera = dxcam.create() # primary output on device 0
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
To specify backend:
|
|
125
|
+
```python
|
|
126
|
+
camera = dxcam.create(
|
|
127
|
+
backend="dxgi", # default Desktop Duplication backend
|
|
128
|
+
processor_backend="cv2" # default OpenCV processor
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Screenshot
|
|
133
|
+
```python
|
|
134
|
+
frame = camera.grab()
|
|
135
|
+
```
|
|
136
|
+
`grab()` returns a `numpy.ndarray`. `None` if no new frame is available since the last capture (for backward compatibility); use `new_frame_only=False` to reuse the latest cached one-shot frame.
|
|
137
|
+
|
|
138
|
+
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.
|
|
139
|
+
|
|
140
|
+
To capture a region:
|
|
141
|
+
```python
|
|
142
|
+
left, top = (1920 - 640) // 2, (1080 - 640) // 2
|
|
143
|
+
right, bottom = left + 640, top + 640
|
|
144
|
+
frame = camera.grab(region=(left, top, right, bottom)) # numpy.ndarray of size (640x640x3) -> (HXWXC)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Screen Capture
|
|
148
|
+
```python
|
|
149
|
+
camera.start(region=(left, top, right, bottom), target_fps=60)
|
|
150
|
+
camera.is_capturing # True
|
|
151
|
+
# ...
|
|
152
|
+
camera.stop()
|
|
153
|
+
camera.is_capturing # False
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### Consume the Screen Capture Data
|
|
157
|
+
```python
|
|
158
|
+
for _ in range(1000):
|
|
159
|
+
frame = camera.get_latest_frame() # blocks until a frame is available
|
|
160
|
+
```
|
|
161
|
+
>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_mode` behavior is designed for downstream video recording and machine learning workloads.
|
|
162
|
+
|
|
163
|
+
Useful variants:
|
|
164
|
+
- `camera.get_latest_frame(with_timestamp=True)` -> `(frame, frame_timestamp)` -> return frame timestamp
|
|
165
|
+
- `camera.get_latest_frame_view()` -> zero-copy view into the frame buffer
|
|
166
|
+
- `camera.grab(copy=False)` / `camera.grab_view()` -> zero-copy latest-frame snapshot
|
|
167
|
+
|
|
168
|
+
> When `start()` capture is running, calling `grab()` reads from the in-memory ring buffer instead of directly polling DXGI.
|
|
169
|
+
|
|
170
|
+
## Advanced Usage and Remarks
|
|
171
|
+
### Multiple monitors / GPUs
|
|
172
|
+
```python
|
|
173
|
+
cam1 = dxcam.create(device_idx=0, output_idx=0)
|
|
174
|
+
cam2 = dxcam.create(device_idx=0, output_idx=1)
|
|
175
|
+
cam3 = dxcam.create(device_idx=1, output_idx=1)
|
|
176
|
+
|
|
177
|
+
img1 = cam1.grab()
|
|
178
|
+
img2 = cam2.grab()
|
|
179
|
+
img3 = cam3.grab()
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Inspect available devices/outputs:
|
|
183
|
+
```pycon
|
|
184
|
+
>>> import dxcam
|
|
185
|
+
>>> print(dxcam.device_info())
|
|
186
|
+
'Device[0]:<Device Name:NVIDIA GeForce RTX 3090 Dedicated VRAM:24348Mb VendorId:4318>\n'
|
|
187
|
+
>>> print(dxcam.output_info())
|
|
188
|
+
'Device[0] Output[0]: Res:(1920, 1080) Rot:0 Primary:True\nDevice[0] Output[1]: Res:(1920, 1080) Rot:0 Primary:False\n'
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Output Format
|
|
192
|
+
Set output color mode when creating the camera:
|
|
193
|
+
```python
|
|
194
|
+
dxcam.create(output_color="BGRA")
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Supported modes: `"RGB"`, `"RGBA"`, `"BGR"`, `"BGRA"`, `"GRAY"`.
|
|
198
|
+
|
|
199
|
+
Notes:
|
|
200
|
+
- Data is returned as `numpy.ndarray`.
|
|
201
|
+
- `BGRA` does not require OpenCV and is the leanest dependency path.
|
|
202
|
+
- `RGB`, `BGR`, `RGBA`, `GRAY` require conversion (`cv2` or compiled `numpy` backend).
|
|
203
|
+
|
|
204
|
+
### Frame Buffer
|
|
205
|
+
DXcam uses a fixed-size ring buffer in-memory. New frames overwrite old frames when full.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
camera = dxcam.create(max_buffer_len=120) # default is 8
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Target FPS
|
|
212
|
+
DXcam uses high-resolution pacing with drift correction to run near `target_fps`.
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
camera.start(target_fps=120) # default to 60, greater than 120 is resource heavy
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
On Python 3.11+, DXcam relies on Windows high-resolution timer behavior used by `time.sleep()`.
|
|
219
|
+
On older versions, DXcam uses WinAPI waitable timers directly.
|
|
220
|
+
|
|
221
|
+
### Frame Timestamp
|
|
222
|
+
Read the most recent frame timestamp (seconds):
|
|
223
|
+
```python
|
|
224
|
+
camera.start(target_fps=60)
|
|
225
|
+
frame, ts = camera.get_latest_frame(with_timestamp=True)
|
|
226
|
+
camera.stop()
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
For `backend="dxgi"`, this value comes from `DXGI_OUTDUPL_FRAME_INFO.LastPresentTime`.
|
|
230
|
+
For `backend="winrt"`, this value is derived from WinRT `SystemRelativeTime`.
|
|
231
|
+
|
|
232
|
+
### Video Mode
|
|
233
|
+
With `video_mode=True`, DXcam fills the buffer at target FPS, reusing the previous frame if needed, even if no new frame is rendered.
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
import cv2
|
|
237
|
+
import dxcam
|
|
238
|
+
|
|
239
|
+
target_fps = 30
|
|
240
|
+
camera = dxcam.create(output_color="BGR")
|
|
241
|
+
camera.start(target_fps=target_fps, video_mode=True)
|
|
242
|
+
|
|
243
|
+
writer = cv2.VideoWriter(
|
|
244
|
+
"video.mp4", cv2.VideoWriter_fourcc(*"mp4v"), target_fps, (1920, 1080)
|
|
245
|
+
)
|
|
246
|
+
for _ in range(600):
|
|
247
|
+
writer.write(camera.get_latest_frame())
|
|
248
|
+
|
|
249
|
+
camera.stop()
|
|
250
|
+
writer.release()
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Capture Backend
|
|
254
|
+
DXcam supports two capture backends:
|
|
255
|
+
- `dxgi` (default): Desktop Duplication API path with broad compatibility.
|
|
256
|
+
- `winrt`: Windows Graphics Capture path.
|
|
257
|
+
|
|
258
|
+
Use it like this:
|
|
259
|
+
```python
|
|
260
|
+
camera = dxcam.create(backend="dxgi") # default
|
|
261
|
+
camera = dxcam.create(backend="winrt")
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Guideline:
|
|
265
|
+
- Start with `dxgi` for most workloads.
|
|
266
|
+
- Try `winrt` if it performs better on your machine or fits your app constraints.
|
|
267
|
+
|
|
268
|
+
### Processor Backend
|
|
269
|
+
DXcam capture backends (`dxgi`/`winrt`) first acquire a BGRA frame.
|
|
270
|
+
The processor backend then handles post-processing:
|
|
271
|
+
- optional rotation/cropping preparation
|
|
272
|
+
- color conversion to your `output_color`
|
|
273
|
+
|
|
274
|
+
Recommended backend choice:
|
|
275
|
+
- OpenCV installed: use `cv2` (default)
|
|
276
|
+
- No OpenCV installed: use `numpy` (Cython kernels)
|
|
277
|
+
|
|
278
|
+
Use it like this:
|
|
279
|
+
```python
|
|
280
|
+
camera = dxcam.create(processor_backend="cv2")
|
|
281
|
+
camera = dxcam.create(processor_backend="numpy")
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Official Windows wheels already include the compiled NumPy kernels.
|
|
285
|
+
|
|
286
|
+
Only for source installs:
|
|
287
|
+
```bash
|
|
288
|
+
set DXCAM_BUILD_CYTHON=1
|
|
289
|
+
pip install -e .[cython] --no-build-isolation
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
If `processor_backend="numpy"` is selected but compiled kernels are unavailable,
|
|
293
|
+
DXcam logs a warning and falls back to `cv2` behavior. In that fallback path,
|
|
294
|
+
install OpenCV for non-`BGRA` output modes.
|
|
295
|
+
|
|
296
|
+
### Safely Releasing Resources
|
|
297
|
+
`release()` stops capture, frees buffers, and releases capture resources.
|
|
298
|
+
After `release()`, the same instance cannot be reused.
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
camera = dxcam.create(output_idx=0, output_color="BGR")
|
|
302
|
+
camera.release()
|
|
303
|
+
# camera.start() # raises RuntimeError
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Benchmarks
|
|
307
|
+
When using a similar logic (only capture newly rendered frames) running on a 240fps output, ```DXCam, python-mss, D3DShot``` benchmarked as follow:
|
|
308
|
+
|
|
309
|
+
| | DXcam | python-mss | D3DShot |
|
|
310
|
+
|-------------|--------|------------|---------|
|
|
311
|
+
| Average FPS | 239.19 :checkered_flag: | 75.87 | 118.36 |
|
|
312
|
+
| Std Dev | 1.25 | 0.5447 | 0.3224 |
|
|
313
|
+
|
|
314
|
+
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](https://www.testufo.com/framerates#count=5&background=stars&pps=960) 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).
|
|
315
|
+
|
|
316
|
+
### For Targeting FPS:
|
|
317
|
+
| (Target)\\(mean,std) | DXcam | python-mss | D3DShot |
|
|
318
|
+
|------------- |-------- |------------|---------|
|
|
319
|
+
| 60fps | 61.71, 0.26 :checkered_flag: | N/A | 47.11, 1.33 |
|
|
320
|
+
| 30fps | 30.08, 0.02 :checkered_flag: | N/A | 21.24, 0.17 |
|
|
321
|
+
|
|
322
|
+
Processor backend comparison helper:
|
|
323
|
+
```bash
|
|
324
|
+
python benchmarks/dxcam_processor_compare.py --backend dxgi --target-fps 120 --target-frames 1000
|
|
325
|
+
python benchmarks/dxcam_capture.py --backend dxgi --processor-backend numpy
|
|
326
|
+
python benchmarks/numpy_processor_micro.py --width 3840 --height 2160 --modes RGB --variants process into --processor-backends cv2 numpy
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## Work Referenced
|
|
331
|
+
|
|
332
|
+
[OBS Studio](https://github.com/obsproject/obs-studio) - implementation ideas and references.
|
|
333
|
+
|
|
334
|
+
[D3DShot](https://github.com/SerpentAI/D3DShot/) : DXcam borrows the ctypes header directly from the no-longer maintained D3DShot.
|