pyedsdk 0.1.0__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.
- pyedsdk-0.1.0/LICENSE.txt +31 -0
- pyedsdk-0.1.0/PKG-INFO +9 -0
- pyedsdk-0.1.0/README.md +62 -0
- pyedsdk-0.1.0/pyedsdk/core/_callbacks.py +46 -0
- pyedsdk-0.1.0/pyedsdk/core/_enums.py +464 -0
- pyedsdk-0.1.0/pyedsdk/core/_errors.py +381 -0
- pyedsdk-0.1.0/pyedsdk/core/_functions.py +299 -0
- pyedsdk-0.1.0/pyedsdk/core/_sdk.py +21 -0
- pyedsdk-0.1.0/pyedsdk/core/_types.py +166 -0
- pyedsdk-0.1.0/pyedsdk/core/loader.py +37 -0
- pyedsdk-0.1.0/pyedsdk/pyedsdk.egg-info/PKG-INFO +9 -0
- pyedsdk-0.1.0/pyedsdk/pyedsdk.egg-info/SOURCES.txt +17 -0
- pyedsdk-0.1.0/pyedsdk/pyedsdk.egg-info/dependency_links.txt +1 -0
- pyedsdk-0.1.0/pyedsdk/pyedsdk.egg-info/requires.txt +7 -0
- pyedsdk-0.1.0/pyedsdk/pyedsdk.egg-info/top_level.txt +3 -0
- pyedsdk-0.1.0/pyedsdk/tests/test_camera.py +22 -0
- pyedsdk-0.1.0/pyedsdk/tests/test_functions.py +190 -0
- pyedsdk-0.1.0/pyproject.toml +21 -0
- pyedsdk-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 François MARGALL
|
|
4
|
+
|
|
5
|
+
This project is an independent Python binding for Canon EDSDK.
|
|
6
|
+
Canon EDSDK is proprietary software owned by Canon Inc. and is
|
|
7
|
+
not distributed with this project.
|
|
8
|
+
This project is not affiliated with, endorsed by, or sponsored
|
|
9
|
+
by Canon Inc.
|
|
10
|
+
|
|
11
|
+
This license applies only to the Python source code of PyEDSDK.
|
|
12
|
+
Users must obtain and comply with Canon’s SDK License Agreement
|
|
13
|
+
separately.
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
pyedsdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyedsdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
License-File: LICENSE.txt
|
|
5
|
+
Requires-Dist: pywin32>=306; platform_system == "Windows"
|
|
6
|
+
Provides-Extra: dev
|
|
7
|
+
Requires-Dist: pytest; extra == "dev"
|
|
8
|
+
Requires-Dist: pytest-timeout; extra == "dev"
|
|
9
|
+
Dynamic: license-file
|
pyedsdk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
## Installation
|
|
2
|
+
|
|
3
|
+
> [!WARNING]
|
|
4
|
+
> - `pyedsdk` currently only supports Windows.
|
|
5
|
+
> - You must download and install the Canon EDSDK separatly from Canon directly.
|
|
6
|
+
> - For intellectual property and licensing reasons, the EDSDK dynamic libraries (`EDSDK.dll`) are not distributed with this Python package.
|
|
7
|
+
|
|
8
|
+
Canon requires developers to request access to the SDK directly from them.
|
|
9
|
+
Please visit the official [Canon Developer website](https://www.canon.fr/business/imaging-solutions/sdk/) and obtain the EDSDK before using this module. This may take a few days before you can have access.
|
|
10
|
+
|
|
11
|
+
### 1. Install Canon EDSDK
|
|
12
|
+
|
|
13
|
+
After downloading the SDK from Canon:
|
|
14
|
+
1. Install or extract the SDK on your machine
|
|
15
|
+
1. Locate the `EDSDK.dll` associated to your architecture (for Windows, either inside `EDSDK` or `EDSDK_64` folder). You can choose to paste it for instance in a new folder located at `C:\Canon\EDSDK\Dll\EDSDK.dll`.
|
|
16
|
+
|
|
17
|
+
### 2. Make the DLL discoverable
|
|
18
|
+
|
|
19
|
+
#### (Recommended) Set environment variable
|
|
20
|
+
|
|
21
|
+
Simply run in your terminal the following command with the path to the DLL:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
setx EDSDK_PATH "C:\Canon\EDSDK\Dll\EDSDK.dll"
|
|
25
|
+
```
|
|
26
|
+
And restart your terminal afterwards.
|
|
27
|
+
|
|
28
|
+
#### (Alternative) Add SDK folder to your PATH
|
|
29
|
+
|
|
30
|
+
Add the directory containing `EDSDK.dll` to your Windows `PATH` environment variable.
|
|
31
|
+
|
|
32
|
+
#### (Alternative) Pass the path explicitly in Python
|
|
33
|
+
|
|
34
|
+
Simply jump to the next part for the installation of the `pyedsdk` package, and when calling it, initialize the DLL with the following code:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from pyedsdk.core.loader import loadSDKLib
|
|
38
|
+
|
|
39
|
+
loadSDKLib(r"C:\Canon\EDSDK\Dll\EDSDK.dll")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Installing `pyedsdk`
|
|
43
|
+
|
|
44
|
+
#### (Recommended) Using `pip`
|
|
45
|
+
|
|
46
|
+
The safest and easiest way to install the latest version is via PyPI:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install pyedsdk
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
This package is an independent, unofficial Python binding for Canon EDSDK. Canon EDSDK is proprietary software owned by Canon Inc. This project:
|
|
55
|
+
- does **not** redistribute Canon binaries
|
|
56
|
+
- does **not** modify Canon SDK files
|
|
57
|
+
- **requires** users to agree to Canon's license separately
|
|
58
|
+
- is **not affiliated with, endorsed by, or sponsored by Canon Inc.**
|
|
59
|
+
|
|
60
|
+
Canon EDSDK remains the exclusive property of Canon Inc. Users are responsible for complying with Canon’s SDK License Agreement.
|
|
61
|
+
|
|
62
|
+
PyEDSDK is distributed under the MIT License. See `License.txt` for more information.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from ._errors import _ErrorCode
|
|
5
|
+
from ._types import _BaseRef
|
|
6
|
+
from ._types import _ObjectEvent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_ObjectEventHandler = ctypes.WINFUNCTYPE(
|
|
10
|
+
ctypes.c_uint32, # _ErrorCode
|
|
11
|
+
ctypes.c_uint32, # _ObjectEvent
|
|
12
|
+
_BaseRef,
|
|
13
|
+
ctypes.c_void_p
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
_PM_REMOVE = 0x0001
|
|
17
|
+
_user32 = ctypes.windll.user32
|
|
18
|
+
|
|
19
|
+
class MSG(ctypes.Structure):
|
|
20
|
+
_fields_ = [
|
|
21
|
+
("hwnd" , ctypes.c_void_p),
|
|
22
|
+
("message", ctypes.c_uint),
|
|
23
|
+
("wParam" , ctypes.c_void_p),
|
|
24
|
+
("lParam" , ctypes.c_void_p),
|
|
25
|
+
("time" , ctypes.c_uint32),
|
|
26
|
+
("pt_x" , ctypes.c_long),
|
|
27
|
+
("pt_y" , ctypes.c_long),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
def _pumpWindowsMessages():
|
|
31
|
+
msg = MSG()
|
|
32
|
+
|
|
33
|
+
while _user32.PeekMessageW(
|
|
34
|
+
ctypes.byref(msg), None, 0, 0, _PM_REMOVE):
|
|
35
|
+
_user32.TranslateMessage(ctypes.byref(msg))
|
|
36
|
+
_user32.DispatchMessageW(ctypes.byref(msg))
|
|
37
|
+
|
|
38
|
+
def _waitForEvent(event, timeout=15):
|
|
39
|
+
start = time.time()
|
|
40
|
+
|
|
41
|
+
while not event.is_set():
|
|
42
|
+
_pumpWindowsMessages()
|
|
43
|
+
time.sleep(0.01)
|
|
44
|
+
|
|
45
|
+
if time.time() - start > timeout:
|
|
46
|
+
raise TimeoutError(f"EDSDK event timeout after {timeout} seconds")
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class _Aperture(IntEnum):
|
|
5
|
+
_f1 = 0x08
|
|
6
|
+
_f1_1 = 0x0B
|
|
7
|
+
_f1_2 = 0x0C
|
|
8
|
+
_f1_2_p = 0x0D
|
|
9
|
+
_f1_4 = 0x10
|
|
10
|
+
_f1_6 = 0x13
|
|
11
|
+
_f1_8 = 0x14
|
|
12
|
+
_f1_8_p = 0x15
|
|
13
|
+
_f2 = 0x18
|
|
14
|
+
_f2_2 = 0x1B
|
|
15
|
+
_f2_5 = 0x1C
|
|
16
|
+
_f2_5_p = 0x1D
|
|
17
|
+
_f2_8 = 0x20
|
|
18
|
+
_f3_2 = 0x23
|
|
19
|
+
_f3_4 = 0x85
|
|
20
|
+
_f3_5 = 0x24
|
|
21
|
+
_f3_5_p = 0x25
|
|
22
|
+
_f4 = 0x28
|
|
23
|
+
_f4_5 = 0x2B
|
|
24
|
+
_f5 = 0x2D
|
|
25
|
+
_f5_6 = 0x30
|
|
26
|
+
_f6_3 = 0x33
|
|
27
|
+
_f6_7 = 0x34
|
|
28
|
+
_f7_1 = 0x35
|
|
29
|
+
_f8 = 0x38
|
|
30
|
+
_f9 = 0x3B
|
|
31
|
+
_f9_5 = 0x3C
|
|
32
|
+
_f10 = 0x3D
|
|
33
|
+
_f11 = 0x40
|
|
34
|
+
_f13_p = 0x43
|
|
35
|
+
_f13 = 0x44
|
|
36
|
+
_f14 = 0x45
|
|
37
|
+
_f16 = 0x48
|
|
38
|
+
_f18 = 0x4B
|
|
39
|
+
_f19 = 0x4C
|
|
40
|
+
_f20 = 0x4D
|
|
41
|
+
_f22 = 0x50
|
|
42
|
+
_f25 = 0x53
|
|
43
|
+
_f27 = 0x54
|
|
44
|
+
_f29 = 0x55
|
|
45
|
+
_f32 = 0x58
|
|
46
|
+
_f36 = 0x5B
|
|
47
|
+
_f38 = 0x5C
|
|
48
|
+
_f40 = 0x5D
|
|
49
|
+
_f45 = 0x60
|
|
50
|
+
_f51 = 0x63
|
|
51
|
+
_f54 = 0x64
|
|
52
|
+
_f57 = 0x65
|
|
53
|
+
_f64 = 0x68
|
|
54
|
+
_f72 = 0x6B
|
|
55
|
+
_f76 = 0x6C
|
|
56
|
+
_f80 = 0x6D
|
|
57
|
+
_f91 = 0x70
|
|
58
|
+
|
|
59
|
+
_Invalid = 0xFFFFFFFF
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def f_number(self) -> float | None:
|
|
63
|
+
if self is self._Invalid:
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
mapping = {
|
|
67
|
+
self._f1 : 1.0,
|
|
68
|
+
self._f1_1 : 1.1,
|
|
69
|
+
self._f1_2 : 1.2,
|
|
70
|
+
self._f1_2_p: 1.2 * (2 ** (1/6)),
|
|
71
|
+
self._f1_4 : 1.4,
|
|
72
|
+
self._f1_6 : 1.6,
|
|
73
|
+
self._f1_8 : 1.8,
|
|
74
|
+
self._f1_8_p: 1.8 * (2 ** (1/6)),
|
|
75
|
+
self._f2 : 2.0,
|
|
76
|
+
self._f2_2 : 2.2,
|
|
77
|
+
self._f2_5 : 2.5,
|
|
78
|
+
self._f2_5_p: 2.5 * (2 ** (1/6)),
|
|
79
|
+
self._f2_8 : 2.8,
|
|
80
|
+
self._f3_2 : 3.2,
|
|
81
|
+
self._f3_4 : 3.4,
|
|
82
|
+
self._f3_5 : 3.5,
|
|
83
|
+
self._f3_5_p: 3.5 * (2 ** (1/6)),
|
|
84
|
+
self._f4 : 4.0,
|
|
85
|
+
self._f4_5 : 4.5,
|
|
86
|
+
self._f5 : 5.0,
|
|
87
|
+
self._f5_6 : 5.6,
|
|
88
|
+
self._f6_3 : 6.3,
|
|
89
|
+
self._f6_7 : 6.7,
|
|
90
|
+
self._f7_1 : 7.1,
|
|
91
|
+
self._f8 : 8.0,
|
|
92
|
+
self._f9 : 9.0,
|
|
93
|
+
self._f9_5 : 9.5,
|
|
94
|
+
self._f10 : 10.0,
|
|
95
|
+
self._f11 : 11.0,
|
|
96
|
+
self._f13_p : 13.0 * (2 ** (1/6)),
|
|
97
|
+
self._f13 : 13.0,
|
|
98
|
+
self._f14 : 14.0,
|
|
99
|
+
self._f16 : 16.0,
|
|
100
|
+
self._f18 : 18.0,
|
|
101
|
+
self._f19 : 19.0,
|
|
102
|
+
self._f20 : 20.0,
|
|
103
|
+
self._f22 : 22.0,
|
|
104
|
+
self._f25 : 25.0,
|
|
105
|
+
self._f27 : 27.0,
|
|
106
|
+
self._f29 : 29.0,
|
|
107
|
+
self._f32 : 32.0,
|
|
108
|
+
self._f36 : 36.0,
|
|
109
|
+
self._f38 : 38.0,
|
|
110
|
+
self._f40 : 40.0,
|
|
111
|
+
self._f45 : 45.0,
|
|
112
|
+
self._f51 : 51.0,
|
|
113
|
+
self._f54 : 54.0,
|
|
114
|
+
self._f57 : 57.0,
|
|
115
|
+
self._f64 : 64.0,
|
|
116
|
+
self._f72 : 72.0,
|
|
117
|
+
self._f76 : 76.0,
|
|
118
|
+
self._f80 : 80.0,
|
|
119
|
+
self._f91 : 91.0,
|
|
120
|
+
}
|
|
121
|
+
return mapping.get(self, None)
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def label(self) -> str:
|
|
125
|
+
if self is self._Invalid:
|
|
126
|
+
return "Not valid"
|
|
127
|
+
|
|
128
|
+
return f"f/{self.f_number}"
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class _ShutterSpeed(IntEnum):
|
|
132
|
+
# Long exposures
|
|
133
|
+
_Bulb = 0x0C
|
|
134
|
+
_30s = 0x10
|
|
135
|
+
_25s = 0x13
|
|
136
|
+
_20s = 0x14
|
|
137
|
+
_20s_p = 0x15 # 20" (1/3)
|
|
138
|
+
_15s = 0x18
|
|
139
|
+
_13s = 0x1B
|
|
140
|
+
_10s = 0x1C
|
|
141
|
+
_10s_p = 0x1D # 10" (1/3)
|
|
142
|
+
_8s = 0x20
|
|
143
|
+
_6s = 0x23
|
|
144
|
+
_6s_p = 0x24 # 6" (1/3)
|
|
145
|
+
_5s = 0x25
|
|
146
|
+
_4s = 0x28
|
|
147
|
+
_3s2 = 0x2B
|
|
148
|
+
_3s = 0x2C
|
|
149
|
+
_2s5 = 0x2D
|
|
150
|
+
_2s = 0x30
|
|
151
|
+
_1s6 = 0x33
|
|
152
|
+
_1s5 = 0x34
|
|
153
|
+
_1s3 = 0x35
|
|
154
|
+
_1s = 0x38
|
|
155
|
+
_0s8 = 0x3B
|
|
156
|
+
_0s7 = 0x3C
|
|
157
|
+
_0s6 = 0x3D
|
|
158
|
+
_0s5 = 0x40
|
|
159
|
+
_0s4 = 0x43
|
|
160
|
+
_0s3 = 0x44
|
|
161
|
+
_0s3_p = 0x45
|
|
162
|
+
|
|
163
|
+
# Fractions
|
|
164
|
+
_1_4 = 0x48
|
|
165
|
+
_1_5 = 0x4B
|
|
166
|
+
_1_6 = 0x4C
|
|
167
|
+
_1_6_p = 0x4D
|
|
168
|
+
_1_8 = 0x50
|
|
169
|
+
_1_10_p = 0x53
|
|
170
|
+
_1_10 = 0x54
|
|
171
|
+
_1_13 = 0x55
|
|
172
|
+
_1_15 = 0x58
|
|
173
|
+
_1_20_p = 0x5B
|
|
174
|
+
_1_20 = 0x5C
|
|
175
|
+
_1_25 = 0x5D
|
|
176
|
+
_1_30 = 0x60
|
|
177
|
+
_1_40 = 0x63
|
|
178
|
+
_1_45 = 0x64
|
|
179
|
+
_1_50 = 0x65
|
|
180
|
+
_1_60 = 0x68
|
|
181
|
+
_1_80 = 0x6B
|
|
182
|
+
_1_90 = 0x6C
|
|
183
|
+
_1_100 = 0x6D
|
|
184
|
+
_1_125 = 0x70
|
|
185
|
+
_1_160 = 0x73
|
|
186
|
+
_1_180 = 0x74
|
|
187
|
+
_1_200 = 0x75
|
|
188
|
+
_1_250 = 0x78
|
|
189
|
+
_1_320 = 0x7B
|
|
190
|
+
_1_350 = 0x7C
|
|
191
|
+
_1_400 = 0x7D
|
|
192
|
+
_1_500 = 0x80
|
|
193
|
+
_1_640 = 0x83
|
|
194
|
+
_1_750 = 0x84
|
|
195
|
+
_1_800 = 0x85
|
|
196
|
+
_1_1000 = 0x88
|
|
197
|
+
_1_1250 = 0x8B
|
|
198
|
+
_1_1500 = 0x8C
|
|
199
|
+
_1_1600 = 0x8D
|
|
200
|
+
_1_2000 = 0x90
|
|
201
|
+
_1_2500 = 0x93
|
|
202
|
+
_1_3000 = 0x94
|
|
203
|
+
_1_3200 = 0x95
|
|
204
|
+
_1_4000 = 0x98
|
|
205
|
+
_1_5000 = 0x9B
|
|
206
|
+
_1_6000 = 0x9C
|
|
207
|
+
_1_6400 = 0x9D
|
|
208
|
+
_1_8000 = 0xA0
|
|
209
|
+
_1_10000 = 0xA3
|
|
210
|
+
_1_12800 = 0xA5
|
|
211
|
+
_1_16000 = 0xA8
|
|
212
|
+
_1_20000 = 0xAB
|
|
213
|
+
_1_25600 = 0xAD
|
|
214
|
+
_1_32000 = 0xB0
|
|
215
|
+
|
|
216
|
+
_Invalid = 0xFFFFFFFF
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def label(self) -> str:
|
|
220
|
+
mapping = {
|
|
221
|
+
self._Bulb : "Bulb",
|
|
222
|
+
self._30s : '30"',
|
|
223
|
+
self._25s : '25"',
|
|
224
|
+
self._20s : '20"',
|
|
225
|
+
self._20s_p : '20" (1/3)',
|
|
226
|
+
self._15s : '15"',
|
|
227
|
+
self._13s : '13"',
|
|
228
|
+
self._10s : '10"',
|
|
229
|
+
self._10s_p : '10" (1/3)',
|
|
230
|
+
self._8s : '8"',
|
|
231
|
+
self._6s : '6"',
|
|
232
|
+
self._6s_p : '6" (1/3)',
|
|
233
|
+
self._5s : '5"',
|
|
234
|
+
self._4s : '4"',
|
|
235
|
+
self._3s2 : '3"2',
|
|
236
|
+
self._3s : '3"',
|
|
237
|
+
self._2s5 : '2"5',
|
|
238
|
+
self._2s : '2"',
|
|
239
|
+
self._1s6 : '1"6',
|
|
240
|
+
self._1s5 : '1"5',
|
|
241
|
+
self._1s3 : '1"3',
|
|
242
|
+
self._1s : '1"',
|
|
243
|
+
self._0s8 : '0"8',
|
|
244
|
+
self._0s7 : '0"7',
|
|
245
|
+
self._0s6 : '0"6',
|
|
246
|
+
self._0s5 : '0"5',
|
|
247
|
+
self._0s4 : '0"4',
|
|
248
|
+
self._0s3 : '0"3',
|
|
249
|
+
self._0s3_p : '0"3 (1/3)',
|
|
250
|
+
self._1_4 : "1/4",
|
|
251
|
+
self._1_5 : "1/5",
|
|
252
|
+
self._1_6 : "1/6",
|
|
253
|
+
self._1_6_p : "1/6 (1/3)",
|
|
254
|
+
self._1_8 : "1/8",
|
|
255
|
+
self._1_10 : "1/10",
|
|
256
|
+
self._1_10_p : "1/10 (1/3)",
|
|
257
|
+
self._1_13 : "1/13",
|
|
258
|
+
self._1_15 : "1/15",
|
|
259
|
+
self._1_20 : "1/20",
|
|
260
|
+
self._1_20_p : "1/20 (1/3)",
|
|
261
|
+
self._1_25 : "1/25",
|
|
262
|
+
self._1_30 : "1/30",
|
|
263
|
+
self._1_40 : "1/40",
|
|
264
|
+
self._1_45 : "1/45",
|
|
265
|
+
self._1_50 : "1/50",
|
|
266
|
+
self._1_60 : "1/60",
|
|
267
|
+
self._1_80 : "1/80",
|
|
268
|
+
self._1_90 : "1/90",
|
|
269
|
+
self._1_100 : "1/100",
|
|
270
|
+
self._1_125 : "1/125",
|
|
271
|
+
self._1_160 : "1/160",
|
|
272
|
+
self._1_180 : "1/180",
|
|
273
|
+
self._1_200 : "1/200",
|
|
274
|
+
self._1_250 : "1/250",
|
|
275
|
+
self._1_320 : "1/320",
|
|
276
|
+
self._1_350 : "1/350",
|
|
277
|
+
self._1_400 : "1/400",
|
|
278
|
+
self._1_500 : "1/500",
|
|
279
|
+
self._1_640 : "1/640",
|
|
280
|
+
self._1_750 : "1/750",
|
|
281
|
+
self._1_800 : "1/800",
|
|
282
|
+
self._1_1000 : "1/1000",
|
|
283
|
+
self._1_1250 : "1/1250",
|
|
284
|
+
self._1_1500 : "1/1500",
|
|
285
|
+
self._1_1600 : "1/1600",
|
|
286
|
+
self._1_2000 : "1/2000",
|
|
287
|
+
self._1_2500 : "1/2500",
|
|
288
|
+
self._1_3000 : "1/3000",
|
|
289
|
+
self._1_3200 : "1/3200",
|
|
290
|
+
self._1_4000 : "1/4000",
|
|
291
|
+
self._1_5000 : "1/5000",
|
|
292
|
+
self._1_6000 : "1/6000",
|
|
293
|
+
self._1_6400 : "1/6400",
|
|
294
|
+
self._1_8000 : "1/8000",
|
|
295
|
+
self._1_10000: "1/10000",
|
|
296
|
+
self._1_12800: "1/12800",
|
|
297
|
+
self._1_16000: "1/16000",
|
|
298
|
+
self._1_20000: "1/20000",
|
|
299
|
+
self._1_25600: "1/25600",
|
|
300
|
+
self._1_32000: "1/32000",
|
|
301
|
+
self._Invalid: "Not valid",
|
|
302
|
+
}
|
|
303
|
+
return mapping.get(self, "Unknown")
|
|
304
|
+
|
|
305
|
+
@property
|
|
306
|
+
def seconds(self) -> float | None:
|
|
307
|
+
if self in {self._Bulb, self._Invalid}:
|
|
308
|
+
return None
|
|
309
|
+
|
|
310
|
+
mapping = {
|
|
311
|
+
# Long exposures
|
|
312
|
+
self._30s : 30.0,
|
|
313
|
+
self._25s : 25.0,
|
|
314
|
+
self._20s : 20.0,
|
|
315
|
+
self._20s_p: 20.0 * (2 ** (-1/3)),
|
|
316
|
+
self._15s : 15.0,
|
|
317
|
+
self._13s : 13.0,
|
|
318
|
+
self._10s : 10.0,
|
|
319
|
+
self._10s_p: 10.0 * (2 ** (-1/3)),
|
|
320
|
+
self._8s : 8.0,
|
|
321
|
+
self._6s : 6.0,
|
|
322
|
+
self._6s_p : 6.0 * (2 ** (-1/3)),
|
|
323
|
+
self._5s : 5.0,
|
|
324
|
+
self._4s : 4.0,
|
|
325
|
+
self._3s2 : 3.2,
|
|
326
|
+
self._3s : 3.0,
|
|
327
|
+
self._2s5 : 2.5,
|
|
328
|
+
self._2s : 2.0,
|
|
329
|
+
self._1s6 : 1.6,
|
|
330
|
+
self._1s5 : 1.5,
|
|
331
|
+
self._1s3 : 1.3,
|
|
332
|
+
self._1s : 1.0,
|
|
333
|
+
self._0s8 : 0.8,
|
|
334
|
+
self._0s7 : 0.7,
|
|
335
|
+
self._0s6 : 0.6,
|
|
336
|
+
self._0s5 : 0.5,
|
|
337
|
+
self._0s4 : 0.4,
|
|
338
|
+
self._0s3 : 0.3,
|
|
339
|
+
self._0s3_p: 0.3 * (2 ** (-1/3)),
|
|
340
|
+
|
|
341
|
+
# Fractions
|
|
342
|
+
self._1_4 : 1/4,
|
|
343
|
+
self._1_5 : 1/5,
|
|
344
|
+
self._1_6 : 1/6,
|
|
345
|
+
self._1_6_p : (1/6) * (2 ** (-1/3)),
|
|
346
|
+
self._1_8 : 1/8,
|
|
347
|
+
self._1_10 : 1/10,
|
|
348
|
+
self._1_10_p : (1/10) * (2 ** (-1/3)),
|
|
349
|
+
self._1_13 : 1/13,
|
|
350
|
+
self._1_15 : 1/15,
|
|
351
|
+
self._1_20 : 1/20,
|
|
352
|
+
self._1_20_p : (1/20) * (2 ** (-1/3)),
|
|
353
|
+
self._1_25 : 1/25,
|
|
354
|
+
self._1_30 : 1/30,
|
|
355
|
+
self._1_40 : 1/40,
|
|
356
|
+
self._1_45 : 1/45,
|
|
357
|
+
self._1_50 : 1/50,
|
|
358
|
+
self._1_60 : 1/60,
|
|
359
|
+
self._1_80 : 1/80,
|
|
360
|
+
self._1_90 : 1/90,
|
|
361
|
+
self._1_100 : 1/100,
|
|
362
|
+
self._1_125 : 1/125,
|
|
363
|
+
self._1_160 : 1/160,
|
|
364
|
+
self._1_180 : 1/180,
|
|
365
|
+
self._1_200 : 1/200,
|
|
366
|
+
self._1_250 : 1/250,
|
|
367
|
+
self._1_320 : 1/320,
|
|
368
|
+
self._1_350 : 1/350,
|
|
369
|
+
self._1_400 : 1/400,
|
|
370
|
+
self._1_500 : 1/500,
|
|
371
|
+
self._1_640 : 1/640,
|
|
372
|
+
self._1_750 : 1/750,
|
|
373
|
+
self._1_800 : 1/800,
|
|
374
|
+
self._1_1000 : 1/1000,
|
|
375
|
+
self._1_1250 : 1/1250,
|
|
376
|
+
self._1_1500 : 1/1500,
|
|
377
|
+
self._1_1600 : 1/1600,
|
|
378
|
+
self._1_2000 : 1/2000,
|
|
379
|
+
self._1_2500 : 1/2500,
|
|
380
|
+
self._1_3000 : 1/3000,
|
|
381
|
+
self._1_3200 : 1/3200,
|
|
382
|
+
self._1_4000 : 1/4000,
|
|
383
|
+
self._1_5000 : 1/5000,
|
|
384
|
+
self._1_6000 : 1/6000,
|
|
385
|
+
self._1_6400 : 1/6400,
|
|
386
|
+
self._1_8000 : 1/8000,
|
|
387
|
+
self._1_10000: 1/10000,
|
|
388
|
+
self._1_12800: 1/12800,
|
|
389
|
+
self._1_16000: 1/16000,
|
|
390
|
+
self._1_20000: 1/20000,
|
|
391
|
+
self._1_25600: 1/25600,
|
|
392
|
+
self._1_32000: 1/32000,
|
|
393
|
+
}
|
|
394
|
+
return mapping.get(self, None)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
class _ISOSpeed(IntEnum):
|
|
398
|
+
_ISO_Auto = 0x00000000
|
|
399
|
+
_ISO_6 = 0x00000028
|
|
400
|
+
_ISO_12 = 0x00000030
|
|
401
|
+
_ISO_25 = 0x00000038
|
|
402
|
+
_ISO_50 = 0x00000040
|
|
403
|
+
_ISO_100 = 0x00000048
|
|
404
|
+
_ISO_125 = 0x0000004B
|
|
405
|
+
_ISO_160 = 0x0000004D
|
|
406
|
+
_ISO_200 = 0x00000050
|
|
407
|
+
_ISO_250 = 0x00000053
|
|
408
|
+
_ISO_320 = 0x00000055
|
|
409
|
+
_ISO_400 = 0x00000058
|
|
410
|
+
_ISO_500 = 0x0000005B
|
|
411
|
+
_ISO_640 = 0x0000005D
|
|
412
|
+
_ISO_800 = 0x00000060
|
|
413
|
+
_ISO_1000 = 0x00000063
|
|
414
|
+
_ISO_1250 = 0x00000065
|
|
415
|
+
_ISO_1600 = 0x00000068
|
|
416
|
+
_ISO_2000 = 0x0000006B
|
|
417
|
+
_ISO_2500 = 0x0000006D
|
|
418
|
+
_ISO_3200 = 0x00000070
|
|
419
|
+
_ISO_4000 = 0x00000073
|
|
420
|
+
_ISO_5000 = 0x00000075
|
|
421
|
+
_ISO_6400 = 0x00000078
|
|
422
|
+
_ISO_8000 = 0x0000007B
|
|
423
|
+
_ISO_10000 = 0x0000007D
|
|
424
|
+
_ISO_12800 = 0x00000080
|
|
425
|
+
_ISO_16000 = 0x00000083
|
|
426
|
+
_ISO_20000 = 0x00000085
|
|
427
|
+
_ISO_25600 = 0x00000088
|
|
428
|
+
_ISO_32000 = 0x0000008B
|
|
429
|
+
_ISO_40000 = 0x0000008D
|
|
430
|
+
_ISO_51200 = 0x00000090
|
|
431
|
+
_ISO_64000 = 0x00000093
|
|
432
|
+
_ISO_80000 = 0x00000095
|
|
433
|
+
_ISO_102400 = 0x00000098
|
|
434
|
+
_ISO_204800 = 0x000000A0
|
|
435
|
+
_ISO_409600 = 0x000000A8
|
|
436
|
+
_ISO_819200 = 0x000000B0
|
|
437
|
+
|
|
438
|
+
@property
|
|
439
|
+
def value(self) -> float:
|
|
440
|
+
if self is _ISOSpeed._ISO_Auto:
|
|
441
|
+
return float("nan")
|
|
442
|
+
|
|
443
|
+
# Enum name is always like "_ISO_6400"
|
|
444
|
+
return float(self.name.split("_")[-1])
|
|
445
|
+
|
|
446
|
+
# Autofocus mode
|
|
447
|
+
class _AFMode(IntEnum):
|
|
448
|
+
_0 = 0
|
|
449
|
+
_1 = 1
|
|
450
|
+
_2 = 2
|
|
451
|
+
_3 = 3
|
|
452
|
+
|
|
453
|
+
_Invalid = 0xFFFFFFFF
|
|
454
|
+
|
|
455
|
+
@property
|
|
456
|
+
def label(self) -> str:
|
|
457
|
+
mapping = {
|
|
458
|
+
self._0: "One-Shot AF",
|
|
459
|
+
self._1: "AI Servo AF",
|
|
460
|
+
self._2: "AI Focus AF",
|
|
461
|
+
self._3: "Manual Focus",
|
|
462
|
+
self._Invalid: "Not valid",
|
|
463
|
+
}
|
|
464
|
+
return mapping.get(self, "Unknown")
|