monochrome 2025.1.31__py3-none-win_amd64.whl → 2025.3.18__py3-none-win_amd64.whl

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.
monochrome/__init__.py CHANGED
@@ -1,6 +1,22 @@
1
+ """Monochrome: Viewer for monochromatic video and image data."""
2
+
1
3
  from ._version import version as __version__
2
- from .ipc import (BitRange, ColorMap, OpacityFunction, show, show_video, show_file, show_files,
3
- show_flow, show_layer, show_points, show_image, export_video, close_video, quit)
4
+ from .ipc import (
5
+ BitRange,
6
+ ColorMap,
7
+ OpacityFunction,
8
+ close_video,
9
+ export_video,
10
+ quit,
11
+ show,
12
+ show_file,
13
+ show_files,
14
+ show_flow,
15
+ show_image,
16
+ show_layer,
17
+ show_points,
18
+ show_video,
19
+ )
4
20
  from .ipc import start_monochrome as launch
5
21
 
6
22
  __all__ = [
@@ -20,4 +36,4 @@ __all__ = [
20
36
  "BitRange",
21
37
  "ColorMap",
22
38
  "OpacityFunction",
23
- ]
39
+ ]
monochrome/__main__.py CHANGED
@@ -3,4 +3,4 @@ import sys
3
3
  from .ipc import console_entrypoint as _main
4
4
 
5
5
  if __name__ == "__main__":
6
- sys.exit(_main())
6
+ sys.exit(_main())
monochrome/_version.py CHANGED
@@ -1,8 +1,13 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
3
6
  TYPE_CHECKING = False
4
7
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
8
+ from typing import Tuple
9
+ from typing import Union
10
+
6
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
7
12
  else:
8
13
  VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
12
17
  __version_tuple__: VERSION_TUPLE
13
18
  version_tuple: VERSION_TUPLE
14
19
 
15
- __version__ = version = '2025.1.31'
16
- __version_tuple__ = version_tuple = (2025, 1, 31)
20
+ __version__ = version = '2025.3.18'
21
+ __version_tuple__ = version_tuple = (2025, 3, 18)
Binary file
@@ -156,8 +156,15 @@ class Array3Meta(object):
156
156
  o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
157
157
  return o == 0
158
158
 
159
+ # Array3Meta
160
+ def Nc(self):
161
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
162
+ if o != 0:
163
+ return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
164
+ return 0
165
+
159
166
  def Array3MetaStart(builder: flatbuffers.Builder):
160
- builder.StartObject(16)
167
+ builder.StartObject(17)
161
168
 
162
169
  def Start(builder: flatbuffers.Builder):
163
170
  Array3MetaStart(builder)
@@ -264,6 +271,12 @@ def Array3MetaStartMetadataVector(builder, numElems: int) -> int:
264
271
  def StartMetadataVector(builder, numElems: int) -> int:
265
272
  return Array3MetaStartMetadataVector(builder, numElems)
266
273
 
274
+ def Array3MetaAddNc(builder: flatbuffers.Builder, nc: int):
275
+ builder.PrependInt32Slot(16, nc, 0)
276
+
277
+ def AddNc(builder: flatbuffers.Builder, nc: int):
278
+ Array3MetaAddNc(builder, nc)
279
+
267
280
  def Array3MetaEnd(builder: flatbuffers.Builder) -> int:
268
281
  return builder.EndObject()
269
282
 
@@ -13,3 +13,6 @@ class ColorMap(IntEnum):
13
13
  PRGN_POS = 6
14
14
  PRGN_NEG = 7
15
15
  RDBU = 8
16
+ TAB10 = 9
17
+ TURBO = 10
18
+ CMOCEAN_PHASE = 11
monochrome/ipc.py CHANGED
@@ -9,35 +9,44 @@ from typing import Dict, List, Optional, Text, Union
9
9
  import flatbuffers
10
10
  import numpy as np
11
11
 
12
- from .fbs import (Array3DataChunkf, Array3DataChunku8, Array3DataChunku16,
13
- Array3Meta, Array3MetaFlow, CloseVideo, Filepaths,
14
- PointsVideo, Root, VideoExport)
12
+ from .fbs import (
13
+ Array3DataChunkf,
14
+ Array3DataChunku8,
15
+ Array3DataChunku16,
16
+ Array3Meta,
17
+ Array3MetaFlow,
18
+ CloseVideo,
19
+ Filepaths,
20
+ PointsVideo,
21
+ Root,
22
+ VideoExport,
23
+ )
15
24
  from .fbs.ArrayDataType import ArrayDataType
16
25
  from .fbs.BitRange import BitRange
17
26
  from .fbs.Color import CreateColor
18
27
  from .fbs.ColorMap import ColorMap
19
28
  from .fbs.Data import Data
20
- from .fbs.VideoExportFormat import VideoExportFormat
21
- from .fbs.DictEntry import (DictEntryAddKey, DictEntryAddVal, DictEntryEnd,
22
- DictEntryStart)
29
+ from .fbs.DictEntry import DictEntryAddKey, DictEntryAddVal, DictEntryEnd, DictEntryStart
23
30
  from .fbs.OpacityFunction import OpacityFunction
31
+ from .fbs.VideoExportFormat import VideoExportFormat
24
32
 
25
- if sys.platform == 'win32':
26
- MONOCHROME_BIN_PATH = Path(__file__).parent / 'data' / 'bin' / 'Monochrome.exe'
27
- elif sys.platform == 'darwin':
28
- MONOCHROME_BIN_PATH = Path(__file__).parent / 'data' / 'Monochrome.app'
33
+ if sys.platform == "win32":
34
+ MONOCHROME_BIN_PATH = Path(__file__).parent / "data" / "bin" / "Monochrome.exe"
35
+ elif sys.platform == "darwin":
36
+ MONOCHROME_BIN_PATH = Path(__file__).parent / "data" / "Monochrome.app"
29
37
  else:
30
- MONOCHROME_BIN_PATH = Path(__file__).parent / 'data' / 'bin' / 'Monochrome'
38
+ MONOCHROME_BIN_PATH = Path(__file__).parent / "data" / "bin" / "Monochrome"
31
39
 
32
- USE_TCP = sys.platform in ['win32', 'cygwin']
33
- TCP_IP, TCP_PORT = '127.0.0.1', 4864
40
+ USE_TCP = sys.platform in ["win32", "cygwin"]
41
+ TCP_IP, TCP_PORT = "127.0.0.1", 4864
34
42
  # OSX doesn't support abstract UNIX domain sockets
35
- ABSTRACT_DOMAIN_SOCKET_SUPPORTED = sys.platform != 'darwin'
36
- if sys.platform != 'win32':
37
- SOCK_PATH = f'\0Monochrome{os.getuid()}' if ABSTRACT_DOMAIN_SOCKET_SUPPORTED else f'/tmp/Monochrome{os.getuid()}.s'
43
+ ABSTRACT_DOMAIN_SOCKET_SUPPORTED = sys.platform != "darwin"
44
+ if sys.platform != "win32":
45
+ SOCK_PATH = f"\0Monochrome{os.getuid()}" if ABSTRACT_DOMAIN_SOCKET_SUPPORTED else f"/tmp/Monochrome{os.getuid()}.s"
38
46
  else:
39
47
  SOCK_PATH = None
40
48
  MAX_BUFFER_SIZE = 16352
49
+ MONOCHROME_DEFAULT_ARGS = {}
41
50
 
42
51
 
43
52
  def start_monochrome(speed: Optional[float] = None,
@@ -46,37 +55,43 @@ def start_monochrome(speed: Optional[float] = None,
46
55
  fliph: bool = False,
47
56
  flipv: bool = False,
48
57
  **kwargs):
49
- """
50
- Start bundled Monochrome executable with the given settings.
51
- """
52
- if sys.platform != 'darwin':
53
- args = [str(MONOCHROME_BIN_PATH)]
54
- else:
55
- args = ['open', '-a', str(MONOCHROME_BIN_PATH), '--args']
58
+ """Start bundled Monochrome executable with the given settings."""
59
+ args = []
56
60
  if speed:
57
- args.append('--speed')
61
+ args.append("--speed")
58
62
  args.append(str(speed))
59
63
  if display_fps:
60
- args.append('--display_fps')
64
+ args.append("--display_fps")
61
65
  args.append(str(display_fps))
62
66
  if scale:
63
- args.append('--scale')
67
+ args.append("--scale")
64
68
  args.append(str(scale))
65
69
  if fliph:
66
- args.append('--fliph')
70
+ args.append("--fliph")
67
71
  if flipv:
68
- args.append('--flipv')
72
+ args.append("--flipv")
73
+ kwargs = {**MONOCHROME_DEFAULT_ARGS, **kwargs}
69
74
  for key, val in kwargs.items():
70
- args.append(f'--{key}')
71
- args.append(str(val))
72
- subprocess.Popen(args, start_new_session=True)
75
+ args.append(f"--{key}")
76
+ if isinstance(val, bool):
77
+ pass
78
+ else:
79
+ args.append(str(val))
80
+
81
+ if sys.platform == "darwin" and '--unit-test-mode' in args:
82
+ cmd = [str(MONOCHROME_BIN_PATH / 'Contents' / 'MacOS' / 'Monochrome'), ] + args
83
+ elif sys.platform == "darwin":
84
+ cmd = ["open", "-a", str(MONOCHROME_BIN_PATH), "--args", ] + args
85
+ else:
86
+ cmd = [str(MONOCHROME_BIN_PATH), ] + args
87
+ subprocess.Popen(cmd, start_new_session=True)
73
88
 
74
89
 
75
90
  def console_entrypoint():
76
- if sys.platform != 'darwin':
91
+ if sys.platform != "darwin":
77
92
  args = [str(MONOCHROME_BIN_PATH)]
78
93
  else:
79
- args = ['open', '-a', str(MONOCHROME_BIN_PATH), '--args']
94
+ args = ["open", "-a", str(MONOCHROME_BIN_PATH), "--args"]
80
95
  args.extend(sys.argv[1:])
81
96
  subprocess.Popen(args).wait()
82
97
 
@@ -185,7 +200,7 @@ def create_pointsvideo_msg(points_py, name, parent_name=None, color=None, point_
185
200
  buf = builder.Output()
186
201
  return buf
187
202
 
188
- def create_array3meta_msg(type: ArrayDataType, name, shape, duration=0., fps=0., date="", comment="",
203
+ def create_array3meta_msg(dtype: ArrayDataType, name, shape, duration=0., fps=0., date="", comment="",
189
204
  bitrange=BitRange.AUTODETECT, cmap=ColorMap.DEFAULT, parent_name=None, opacity=None,
190
205
  metadata=None, vmin=None, vmax=None):
191
206
  builder = flatbuffers.Builder(1024)
@@ -194,7 +209,7 @@ def create_array3meta_msg(type: ArrayDataType, name, shape, duration=0., fps=0.,
194
209
  date_fb = builder.CreateString(date)
195
210
  comment_fb = builder.CreateString(comment)
196
211
  if metadata:
197
- metadata = [(builder.CreateString(key), builder.CreateString(val)) for key, val in metadata.items()]
212
+ metadata = [(builder.CreateString(key), builder.CreateString(str(val))) for key, val in metadata.items()]
198
213
  metaData_fbs = []
199
214
  for key, val in metadata:
200
215
  DictEntryStart(builder)
@@ -206,10 +221,10 @@ def create_array3meta_msg(type: ArrayDataType, name, shape, duration=0., fps=0.,
206
221
  builder.PrependUOffsetTRelative(e)
207
222
  metadata = builder.EndVector()
208
223
  Array3Meta.Start(builder)
209
- Array3Meta.AddType(builder, type)
224
+ Array3Meta.AddType(builder, dtype)
210
225
  Array3Meta.AddNx(builder, shape[2])
211
226
  Array3Meta.AddNy(builder, shape[1])
212
- Array3Meta.AddNt(builder, shape[0])
227
+ Array3Meta.AddNt(builder, shape[0] * shape[3])
213
228
  Array3Meta.AddBitrange(builder, bitrange)
214
229
  Array3Meta.AddCmap(builder, cmap)
215
230
  if vmin is not None:
@@ -227,6 +242,7 @@ def create_array3meta_msg(type: ArrayDataType, name, shape, duration=0., fps=0.,
227
242
  Array3Meta.AddComment(builder, comment_fb)
228
243
  if metadata:
229
244
  Array3Meta.AddMetadata(builder, metadata)
245
+ Array3Meta.AddNc(builder, shape[3])
230
246
  d = Array3Meta.End(builder)
231
247
 
232
248
  root = build_root(builder, Data.Array3Meta, d)
@@ -302,7 +318,7 @@ def create_array3datau16_msg(array, idx=0):
302
318
  def show_file(filepath: Union[Text, Path]):
303
319
  """
304
320
  Load a file in Monochrome.
305
-
321
+
306
322
  Parameters
307
323
  ----------
308
324
  filepath : str or Path
@@ -347,7 +363,6 @@ def show_points(points, name: Text = "", parent: Optional[Text] = None, color=No
347
363
  point_size : float
348
364
  Size of points in image pixels
349
365
  """
350
-
351
366
  name = str(name)
352
367
  s = create_socket()
353
368
  buf = create_pointsvideo_msg(points, name, parent, color, point_size)
@@ -366,7 +381,7 @@ def show_image(array: np.ndarray,
366
381
  metadata: Optional[Dict] = None):
367
382
  """
368
383
  Show an image in Monochrome.
369
-
384
+
370
385
  Alias for :func:`show_video`.
371
386
  """
372
387
  return show_video(array, name=name, cmap=cmap, vmin=vmin, vmax=vmax, bitrange=bitrange, parent=parent, opacity=opacity, comment=comment, metadata=metadata)
@@ -382,10 +397,10 @@ def show_video(array: np.ndarray,
382
397
  opacity: Optional[OpacityFunction] = None,
383
398
  comment: Text = "",
384
399
  metadata: Optional[Dict] = None):
385
- """
386
- Play a video or open a image in Monochrome.
400
+ """Play a video or open a image in Monochrome.
401
+
387
402
  Arrays of dtype np.float, np.uint8, and np.uint16 are natively supported by Monochrome.
388
- Arrays with other dtypes will be converted to np.float
403
+ Arrays with other dtypes will be converted to np.float32.
389
404
 
390
405
  Parameters
391
406
  ----------
@@ -394,7 +409,7 @@ def show_video(array: np.ndarray,
394
409
  name : str
395
410
  Name of the video
396
411
  cmap : str or ColorMap
397
- Colormap for the video. One of 'default' (autodetect), 'gray', 'hsv', 'blackbody', 'viridis', 'PRGn', 'PRGn_pos', 'PRGn_neg', 'RdBu'.
412
+ Colormap for the video. One of 'default' (autodetect), 'gray', 'hsv', 'blackbody', 'viridis', 'PRGn', 'PRGn_pos', 'PRGn_neg', 'RdBu', 'tab10'.
398
413
  vmin : float
399
414
  Minimum value for the colormap. Default is None.
400
415
  vmax : float
@@ -410,13 +425,26 @@ def show_video(array: np.ndarray,
410
425
  metadata : dict
411
426
  Additional metadata to be displayed
412
427
  """
413
-
414
428
  array = np.squeeze(array)
415
429
  if array.ndim == 2:
416
430
  # assume that it is a 2D image
417
- array = np.expand_dims(array, 0)
418
- elif array.ndim != 3:
419
- raise ValueError("array is not two- or three-dimensional")
431
+ array = array[np.newaxis, :, :, np.newaxis]
432
+ elif array.ndim == 3:
433
+ if array.shape[2] in (3, 4):
434
+ # assume that it is an RGB(A) image
435
+ if array.shape[2] == 4:
436
+ # alpha channel is not yet supported
437
+ array = array[..., :3]
438
+ array = np.expand_dims(array, 0)
439
+ else:
440
+ array = np.expand_dims(array, -1)
441
+ elif array.ndim == 4:
442
+ if array.shape[3] not in (3, 4):
443
+ msg = f"Video has an unsupported shape {array.shape}. Four dimensional arrays are only supported if the last dimension is 3 (RGB) or 4 (RGBA)."
444
+ raise ValueError(msg)
445
+ else:
446
+ msg = f"Array does not have an image/video shape: Shape {array.shape}"
447
+ raise ValueError(msg)
420
448
 
421
449
  if array.dtype == np.float32:
422
450
  dtype = ArrayDataType.FLOAT
@@ -482,7 +510,7 @@ def show_video(array: np.ndarray,
482
510
  def show_layer(array: np.ndarray, name: Text = "", parent: Optional[Text] = None, opacity: Optional[OpacityFunction] = None, **kwargs):
483
511
  """
484
512
  Add a layer to the parent video in Monochrome.
485
-
513
+
486
514
  Parameters
487
515
  ----------
488
516
  array : np.ndarray
@@ -553,9 +581,10 @@ def show(array_or_path: Union[str, Path, np.ndarray], *args, **kwargs):
553
581
  def export_video(filepath, name="", fps=30, t_start=0, t_end=-1, description="", close_after_completion=False):
554
582
  """Export a video displayed in Monochrome to a .mp4 file.
555
583
 
556
- NOTE: Monochrome exports the video as rendered in the window, i.e. the video will have the same resolution as
557
- the video window and all the layers/points/... will be merged into a single video.
558
-
584
+ .. note::
585
+ Monochrome exports the video as rendered in the window, i.e. the video will have the same resolution as
586
+ the video window and all the layers/points/... will be merged into a single video.
587
+
559
588
  Parameters
560
589
  ----------
561
590
  filepath : str
@@ -596,7 +625,7 @@ def export_video(filepath, name="", fps=30, t_start=0, t_end=-1, description="",
596
625
 
597
626
  def close_video(name=""):
598
627
  """Close a video in Monochrome.
599
-
628
+
600
629
  Parameters
601
630
  ----------
602
631
  name : str
@@ -614,7 +643,7 @@ def close_video(name=""):
614
643
  buf = builder.Output()
615
644
  s.sendall(buf)
616
645
 
617
- def quit():
646
+ def quit(): # noqa: A001
618
647
  """Quit Monochrome, terminating the process."""
619
648
  s = create_socket()
620
649
  builder = flatbuffers.Builder(512)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: monochrome
3
- Version: 2025.1.31
3
+ Version: 2025.3.18
4
4
  Summary: Viewer for monochromatic video data
5
5
  Author-Email: Jan Lebert <mail@janlebert.com>
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -19,8 +19,10 @@ Project-URL: Repository, https://github.com/sitic/monochrome
19
19
  Requires-Python: >=3.6
20
20
  Requires-Dist: numpy
21
21
  Requires-Dist: flatbuffers>=23.5.26
22
+ Provides-Extra: test
22
23
  Requires-Dist: pytest; extra == "test"
23
- Requires-Dist: sphinx; extra == "docs"
24
+ Provides-Extra: docs
25
+ Requires-Dist: sphinx==8.1.3; extra == "docs"
24
26
  Requires-Dist: sphinxcontrib-napoleon; extra == "docs"
25
27
  Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
26
28
  Requires-Dist: sphinxcontrib-video; extra == "docs"
@@ -35,8 +37,6 @@ Requires-Dist: sphinx-remove-toctrees; extra == "docs"
35
37
  Requires-Dist: sphinx-design; extra == "docs"
36
38
  Requires-Dist: enum-tools[sphinx]; extra == "docs"
37
39
  Requires-Dist: opticalmapping[all]; extra == "docs"
38
- Provides-Extra: test
39
- Provides-Extra: docs
40
40
  Description-Content-Type: text/markdown
41
41
 
42
42
  # Monochrome: Viewer for Monochromatic Video Data
@@ -45,7 +45,9 @@ Description-Content-Type: text/markdown
45
45
  [![PyPI](https://img.shields.io/pypi/v/monochrome.svg)](https://pypi.org/project/monochrome/)
46
46
  [![Supported Python versions](https://img.shields.io/pypi/pyversions/monochrome.svg)](https://python.org)
47
47
 
48
- Monochrome is a lightweight and fast video viewer for scientific monochromatic videos with high-dynamic range (float, uint16, etc.).
48
+ Monochrome is a lightweight and fast viewer for scientific imaging and video data with a focus on monochromatic data and high-dynamic range data. It is designed to be fast and lightweight, i.e. it uses memory-mapping to load video files to avoid copying the data into RAM.
49
+
50
+ ![Monochrome](https://raw.githubusercontent.com/sitic/monochrome/refs/heads/master/assets/Monochrome-screenshot1.webp)
49
51
 
50
52
  It is designed for viewing high-speed monochromatic fluorescence video data from scientific cameras and meet our specific needs for cardiac optical mapping data (together with [optimap](https://github.com/cardiacvision/optimap)):
51
53
  * Support for high-dynamic range (uint16, 32-bit float) data with sliders to adjust intensity range
@@ -120,14 +122,29 @@ mc.show_layer(overlay, parent="Second Video", cmap='PRGn', opacity='centered')
120
122
  # mc.quit() to close Monochrome
121
123
  ```
122
124
 
123
- ## Native Video File Formats
124
- Monochrome supports loading the following video file formats:
125
+ ## Supported File Formats
126
+
127
+ Monochrome supports a wide range of file formats through both native handlers and a plugin system.
128
+
129
+ ### Native File Handlers
130
+
131
+ * `.tif`, `.tiff` - TIFF image files (single or multi-page)
132
+ * Directory of TIFF files - Loads a directory containing TIFF images as a single video
133
+ * `.npy` - NumPy array with shape (time, height, width). The data type can be float (np.float32, np.float64), integer (uint8, uint16, etc.), or boolean.
134
+ * `.dat` - Raw binary file with shape (time, height, width) and data type float32 or MultiRecorder file format (used in the cardiac optical mapping community)
135
+
136
+ ### Plugin-Based File Handlers
137
+
138
+ Monochrome uses a plugin system to support additional file formats:
125
139
 
126
- * `.npy`, NumPy array with shape (time, width, height). The data type can be float (np.float32, np.float64), integer (uint8, uint16, etc.), or boolean.
127
- * `.dat`, raw binary file with shape (time, width, height) and data type float32
128
- * `.dat`, MultiRecorder file format (used in the cardiac optical mapping community)
140
+ * **Image Formats**: `.png`, `.jpg`, `.jpeg`, `.webp`, `.bmp`, `.pgm`
141
+ * **TIFF Variants**: `.tf8`, `.ptif`, `.ptiff`, `.lsm` (ZEISS LSM), `.btf`, `.bif` (Roche Digital Pathology), `.gel`, `.ndpi` (Hamamatsu Slide Scanner), `.stk`, `.qptiff` (Perkin Elmer Vectra)
142
+ * **Medical Imaging**: `.dcm`, `.dicom`, `.gdcm`, `.gipl`, `.hdf5`, `.hdr`, `.ipl`, `.img`, `.img.nz`, `.mgh`, `.mha`, `.mhd`, `.mnc`, `.mnc2`, `.nhdr`, `.nia`, `.nii`, `.nii.gz`, `.nrrd`, `.vtk`
143
+ * **Video Formats**: `.mp4`, `.avi`, `.webm`, `.mov`, `.mkv`, `.gif`, `.wmv`, `.m4v`
144
+ * **MATLAB**: `.mat`
145
+ * **MiCAM Formats**: `.gsd`, `.gsh`, `.rsh`, `.rsm`, `.rsd` (MiCAM camera formats)
129
146
 
130
- Drag & drop the file into the window or associate the file extension with Monochrome to open it with a double-click.
147
+ Drag & drop files into the window or associate the file extension with Monochrome to open them with a double-click. Required plugin dependencies will be downloaded automatically when opening files that need them.
131
148
 
132
149
  ## Usage & Key Bindings
133
150
 
@@ -139,6 +156,8 @@ Keyboard shortcuts:
139
156
  | --- | --- |
140
157
  | `Ctrl + q` | Quit Monochrome |
141
158
  | `Esc` or `q` | Close focused recording |
159
+ | `Ctrl + o` | Open media file |
160
+ | `Ctrl + Shift + o` | Open png/tiff/dcm file folder |
142
161
  | `Space` | Play/Pause |
143
162
  | `Up` | Increase playback speed (frame skip) |
144
163
  | `Down` | Decrease playback speed (frame skip) |
@@ -1,18 +1,18 @@
1
- monochrome/__init__.py,sha256=K9n6ztGQJhtcB8deigemASPJbg-1tjuQbSe_mfPNdV4,596
2
- monochrome/__main__.py,sha256=Jj4xELPOHEEY4tfjPs7w_T9hEjBF4T9PXhdqTGKNfKg,111
3
- monochrome/_version.py,sha256=gahe8xaQzoJYYaxfHPHhvVbz9Q_ipVaXMgXl9Nss0Vk,435
4
- monochrome/data/bin/Monochrome.exe,sha256=Q-iy1hVhvGiTDxVR3bgPhRLB-xpCh77XJvDQUkwwBes,3080704
1
+ monochrome/__init__.py,sha256=ud708EyRBkml6sSl3bY0Zan1WBPQwoBAyuG5TaG8fBo,917
2
+ monochrome/__main__.py,sha256=e10poFhP9QZtWi_TRreuCZpxtHtJSdFyOnaiBTkBgyw,113
3
+ monochrome/_version.py,sha256=y9zYYDbmaj5vySQtEuQ4pijLPWupR_LmzvsNYNXB8rw,540
4
+ monochrome/data/bin/Monochrome.exe,sha256=IxofE_RKFPUj98Db7X_Mhhh7u5gIfut9Mfw7IbAQ9nU,5556736
5
5
  monochrome/fbs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  monochrome/fbs/Array3DataChunkf.py,sha256=BOjp4LGcdpQiEtg2pgJxmgapwu6OSnIXGZaUUq91KzU,3166
7
7
  monochrome/fbs/Array3DataChunku16.py,sha256=XtZv5L1fHaXS7tdplPgNGICVp3pLWPO6fV-dXn7ablY,3202
8
8
  monochrome/fbs/Array3DataChunku8.py,sha256=9HLKxxJD8KG9JKeOhdlJCofDTgTmGoiSgBkRT70--nE,3181
9
- monochrome/fbs/Array3Meta.py,sha256=CfnzQm5SvE_Tjiqn9PUMljJ37bZ4igVmaWxAs0JoC2A,9689
9
+ monochrome/fbs/Array3Meta.py,sha256=bgRuxXFt47OvMgSJA6J1cJIP_TaI46J5tbmGDgnk678,10129
10
10
  monochrome/fbs/Array3MetaFlow.py,sha256=VgQUVuhMdrFz6m5GuxMCqg7saMS21LHtWqsEoMB5QLo,4201
11
11
  monochrome/fbs/ArrayDataType.py,sha256=lute99L_Zh9sbLRxl1k13X0hqEp2Qhhi1dY3MEvDKck,195
12
12
  monochrome/fbs/BitRange.py,sha256=E1yT-kOzdilhgCVrEUKyLvM7JOrg8IUprf6YXmIvf0k,322
13
13
  monochrome/fbs/CloseVideo.py,sha256=IG1P6PI5mMrsdWM0EGUoXNNR0p508EWk0hmF8d8g1wQ,1636
14
14
  monochrome/fbs/Color.py,sha256=z2wSydIqYfunYRKwzEGI2B06tQHv5ocLcaGYDFSXtd4,1415
15
- monochrome/fbs/ColorMap.py,sha256=yXw7BhStk97kAPFkmqlZ7XTLU6WbzaW3seeRiMkJiyo,288
15
+ monochrome/fbs/ColorMap.py,sha256=pDcuBWueT9wm9mePag-GG3X_BpEfK4t9BRmAszGuYlE,343
16
16
  monochrome/fbs/Data.py,sha256=T3Kx7EBaHGU0hBZ-hHtNjRjb1DnaT4AYccAnS8qmXVo,375
17
17
  monochrome/fbs/DictEntry.py,sha256=gztgZ7-PAgDCx02RFZf6tQ0OzRDg0mWnRxhvUwp7bvs,2105
18
18
  monochrome/fbs/Filepaths.py,sha256=2EJBdPAlv4pF81AosFuVZu_Y90yi9XahiDINPG1jsfQ,2258
@@ -22,9 +22,9 @@ monochrome/fbs/Quit.py,sha256=xJhsWUvABgK9PznKnPVOFfr37JZXMAuiAL6iJ3Hxwrk,1060
22
22
  monochrome/fbs/Root.py,sha256=Wb5Q8q1jqcQKcjV_u33tGjUGDueBn_-vAUVNdyct_7g,2141
23
23
  monochrome/fbs/VideoExport.py,sha256=u6hS-TbPvz4vUdoue-FRNx21AtRslm8RH7T-LGJt7eo,5243
24
24
  monochrome/fbs/VideoExportFormat.py,sha256=qR6xpBFK3zZf8uTtOFdhWGHrDvroKRxCSDuPR8bdu0w,182
25
- monochrome/ipc.py,sha256=6YA0aeXWb0KK9w56uBFhlULaNGjDgjcXFoSQvv2e-vE,22624
26
- monochrome-2025.1.31.dist-info/METADATA,sha256=d7An1IjFNre6so7jM_DoYEx0jlrLOLlzU2ZVMSEmhrk,8338
27
- monochrome-2025.1.31.dist-info/WHEEL,sha256=EShulKv4epvXf2hxJKX50LEbDeR3f4CaySDu_eXD8pg,103
28
- monochrome-2025.1.31.dist-info/entry_points.txt,sha256=wnWVyp2qn7QtxN2OhtX4AY0a1c8liGuhOS73CFYe0iM,62
29
- monochrome-2025.1.31.dist-info/licenses/LICENSE.md,sha256=ONCQDA6lwlpvDNkB_le4Pn8DuMr1huK2DUzgG-f-BTE,1073
30
- monochrome-2025.1.31.dist-info/RECORD,,
25
+ monochrome/ipc.py,sha256=LPydu3tyfmQPdnZo2jZojYYhpnwYBeXf7YnAvl_8rXE,23665
26
+ monochrome-2025.3.18.dist-info/METADATA,sha256=uzWcWaNp-e2eeH6XDURmRp87nEpZt-8rFiUjYDQ-sY8,9743
27
+ monochrome-2025.3.18.dist-info/WHEEL,sha256=QVvQyceONrQFRxko1Jifw1vmo8podRpkc8zfhwmIIMM,103
28
+ monochrome-2025.3.18.dist-info/entry_points.txt,sha256=wnWVyp2qn7QtxN2OhtX4AY0a1c8liGuhOS73CFYe0iM,62
29
+ monochrome-2025.3.18.dist-info/licenses/LICENSE.md,sha256=ONCQDA6lwlpvDNkB_le4Pn8DuMr1huK2DUzgG-f-BTE,1073
30
+ monochrome-2025.3.18.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: scikit-build-core 0.10.7
2
+ Generator: scikit-build-core 0.11.0
3
3
  Root-Is-Purelib: false
4
4
  Tag: py3-none-win_amd64
5
5