0
# Input/Output Operations
1
2
Comprehensive input/output capabilities including image I/O, LUT processing, spectral data file handling, and various file format support. The I/O system provides robust reading and writing capabilities across multiple formats with automatic format detection and validation.
3
4
## Capabilities
5
6
### Image Input/Output
7
8
Core functions for reading and writing images across various formats with support for multiple backends and bit depth handling.
9
10
```python { .api }
11
def read_image(path: Union[str, Path], method: str = None, **kwargs) -> NDArray:
12
"""
13
Read an image from disk using the specified method.
14
15
Parameters:
16
- path: path to the image file
17
- method: reading method ('OpenImageIO' or 'Imageio'), auto-detected if None
18
- **kwargs: additional arguments passed to the specific reading method
19
20
Returns:
21
Image data as numpy array with shape (height, width, channels)
22
23
Supported formats: PNG, JPEG, TIFF, EXR, HDR, PFM, and many others
24
"""
25
26
def write_image(image: ArrayLike, path: Union[str, Path], bit_depth: Union[str, int] = None,
27
method: str = None, **kwargs) -> bool:
28
"""
29
Write an image to disk using the specified method.
30
31
Parameters:
32
- image: image data as array-like (height, width, channels)
33
- path: output file path
34
- bit_depth: bit depth for output ('uint8', 'uint16', 'float32', etc.)
35
- method: writing method ('OpenImageIO' or 'Imageio'), auto-detected if None
36
- **kwargs: additional arguments passed to the specific writing method
37
38
Returns:
39
True if successful, False otherwise
40
"""
41
42
def read_image_OpenImageIO(path: Union[str, Path], bit_depth: str = "float32",
43
attributes: bool = True, **kwargs) -> Union[NDArray, Tuple[NDArray, dict]]:
44
"""
45
Read an image using OpenImageIO backend.
46
47
Parameters:
48
- path: path to the image file
49
- bit_depth: target bit depth ('uint8', 'uint16', 'float16', 'float32')
50
- attributes: whether to return image attributes
51
- **kwargs: additional OpenImageIO parameters
52
53
Returns:
54
Image array, or tuple of (image array, attributes dict) if attributes=True
55
"""
56
57
def write_image_OpenImageIO(image: ArrayLike, path: Union[str, Path], bit_depth: str = "float32",
58
attributes: List[Image_Specification_Attribute] = None, **kwargs) -> bool:
59
"""
60
Write an image using OpenImageIO backend.
61
62
Parameters:
63
- image: image data as array-like
64
- path: output file path
65
- bit_depth: output bit depth ('uint8', 'uint16', 'float16', 'float32')
66
- attributes: list of image attributes to embed
67
- **kwargs: additional OpenImageIO parameters
68
69
Returns:
70
True if successful
71
"""
72
73
def read_image_Imageio(path: Union[str, Path], **kwargs) -> NDArray:
74
"""
75
Read an image using Imageio backend.
76
77
Parameters:
78
- path: path to the image file
79
- **kwargs: additional imageio parameters
80
81
Returns:
82
Image data as numpy array
83
"""
84
85
def write_image_Imageio(image: ArrayLike, path: Union[str, Path], **kwargs) -> bool:
86
"""
87
Write an image using Imageio backend.
88
89
Parameters:
90
- image: image data as array-like
91
- path: output file path
92
- **kwargs: additional imageio parameters
93
94
Returns:
95
True if successful
96
"""
97
```
98
99
### Image Specification and Attributes
100
101
Classes and utilities for handling image metadata and bit depth specifications.
102
103
```python { .api }
104
@dataclass
105
class Image_Specification_Attribute:
106
"""
107
Define an image specification attribute for metadata embedding.
108
109
Attributes:
110
- name: attribute name (str)
111
- value: attribute value (Any)
112
- type_: attribute type hint (Type, optional)
113
"""
114
name: str
115
value: Any
116
type_: Type = None
117
118
@dataclass(frozen=True)
119
class Image_Specification_BitDepth:
120
"""
121
Define a bit-depth specification for image processing.
122
123
Attributes:
124
- name: bit depth name (str)
125
- numpy: numpy data type
126
- openimageio: OpenImageIO type specification
127
"""
128
name: str
129
numpy: Type[DTypeReal]
130
openimageio: Any
131
132
def convert_bit_depth(a: ArrayLike, bit_depth: str) -> NDArray:
133
"""
134
Convert array to specified bit depth with proper scaling.
135
136
Parameters:
137
- a: input array
138
- bit_depth: target bit depth ('uint8', 'uint16', 'float32', etc.)
139
140
Returns:
141
Array converted to target bit depth
142
"""
143
144
def as_3_channels_image(a: ArrayLike) -> NDArray:
145
"""
146
Convert array to 3-channel image format.
147
148
Parameters:
149
- a: input image array (1, 2, 3, or 4 channels)
150
151
Returns:
152
3-channel image array (RGB)
153
"""
154
155
MAPPING_BIT_DEPTH: dict = {
156
"uint8": Image_Specification_BitDepth("uint8", np.uint8, ...),
157
"uint16": Image_Specification_BitDepth("uint16", np.uint16, ...),
158
"float16": Image_Specification_BitDepth("float16", np.float16, ...),
159
"float32": Image_Specification_BitDepth("float32", np.float32, ...),
160
# ... additional bit depth mappings
161
}
162
"""Mapping of bit depth names to specifications."""
163
```
164
165
### LUT Classes and Processing
166
167
Comprehensive Look-Up Table classes for 1D, 3x1D, and 3D transformations with interpolation and manipulation capabilities.
168
169
```python { .api }
170
class LUT1D:
171
"""
172
1D Look-Up Table for single-channel transformations.
173
174
Parameters:
175
- table: 1D array of LUT values, or None for linear table
176
- name: LUT name (str, optional)
177
- domain: input domain range as [min, max] array
178
- size: LUT size (int, used if table is None)
179
- comments: list of comment strings
180
"""
181
def __init__(self, table: ArrayLike = None, name: str = None,
182
domain: ArrayLike = None, size: int = None,
183
comments: Sequence[str] = None): ...
184
185
@property
186
def table(self) -> NDArray: ...
187
@property
188
def name(self) -> str: ...
189
@property
190
def domain(self) -> NDArray: ...
191
@property
192
def size(self) -> int: ...
193
@property
194
def comments(self) -> List[str]: ...
195
196
def apply(self, RGB: ArrayLike, interpolator: str = "Linear",
197
interpolator_kwargs: dict = None, **kwargs) -> NDArray:
198
"""Apply 1D LUT to input values with interpolation."""
199
200
def copy(self) -> "LUT1D":
201
"""Return a copy of the LUT."""
202
203
def invert(self, **kwargs) -> "LUT1D":
204
"""Return inverted LUT."""
205
206
@staticmethod
207
def linear_table(size: int = 33, domain: ArrayLike = None) -> NDArray:
208
"""Generate a linear table for the given size and domain."""
209
210
class LUT3x1D:
211
"""
212
3x1D Look-Up Table for independent per-channel transformations.
213
214
Parameters:
215
- table: 2D array of shape (size, 3) with RGB channel LUTs
216
- name: LUT name (str, optional)
217
- domain: input domain range as [[R_min, G_min, B_min], [R_max, G_max, B_max]]
218
- size: LUT size (int, used if table is None)
219
- comments: list of comment strings
220
"""
221
def __init__(self, table: ArrayLike = None, name: str = None,
222
domain: ArrayLike = None, size: int = None,
223
comments: Sequence[str] = None): ...
224
225
@property
226
def table(self) -> NDArray: ...
227
@property
228
def name(self) -> str: ...
229
@property
230
def domain(self) -> NDArray: ...
231
@property
232
def size(self) -> int: ...
233
@property
234
def comments(self) -> List[str]: ...
235
236
def apply(self, RGB: ArrayLike, interpolator: str = "Linear",
237
interpolator_kwargs: dict = None, **kwargs) -> NDArray:
238
"""Apply 3x1D LUT to RGB input with per-channel interpolation."""
239
240
def copy(self) -> "LUT3x1D": ...
241
def invert(self, **kwargs) -> "LUT3x1D": ...
242
243
@staticmethod
244
def linear_table(size: int = 33, domain: ArrayLike = None) -> NDArray: ...
245
246
class LUT3D:
247
"""
248
3D Look-Up Table for full 3D colour transformations.
249
250
Parameters:
251
- table: 4D array of shape (size_r, size_g, size_b, 3) with RGB output values
252
- name: LUT name (str, optional)
253
- domain: input domain range as [[R_min, G_min, B_min], [R_max, G_max, B_max]]
254
- size: LUT size (int or array-like, used if table is None)
255
- comments: list of comment strings
256
"""
257
def __init__(self, table: ArrayLike = None, name: str = None,
258
domain: ArrayLike = None, size: Union[int, ArrayLike] = None,
259
comments: Sequence[str] = None): ...
260
261
@property
262
def table(self) -> NDArray: ...
263
@property
264
def name(self) -> str: ...
265
@property
266
def domain(self) -> NDArray: ...
267
@property
268
def size(self) -> Union[int, NDArray]: ...
269
@property
270
def comments(self) -> List[str]: ...
271
272
def apply(self, RGB: ArrayLike, interpolator: str = "Trilinear",
273
interpolator_kwargs: dict = None, **kwargs) -> NDArray:
274
"""Apply 3D LUT to RGB input with trilinear interpolation."""
275
276
def copy(self) -> "LUT3D": ...
277
def invert(self, **kwargs) -> "LUT3D": ...
278
279
@staticmethod
280
def linear_table(size: Union[int, ArrayLike] = 33, domain: ArrayLike = None) -> NDArray: ...
281
282
class LUTSequence:
283
"""
284
Sequence of LUTs and operators applied in order.
285
286
Parameters:
287
- sequence: list of LUT objects and operators
288
- name: sequence name (str, optional)
289
- comments: list of comment strings
290
"""
291
def __init__(self, sequence: List = None, name: str = None,
292
comments: Sequence[str] = None): ...
293
294
def apply(self, RGB: ArrayLike, **kwargs) -> NDArray:
295
"""Apply the entire LUT sequence to input RGB."""
296
297
def append(self, LUT: Union[LUT1D, LUT3x1D, LUT3D]) -> None:
298
"""Append a LUT to the sequence."""
299
300
class LUTOperatorMatrix:
301
"""
302
Matrix operator for LUT sequences (scaling, offset, matrix multiplication).
303
304
Parameters:
305
- matrix: 4x4 transformation matrix
306
- offset: offset vector (4 elements)
307
- name: operator name (str, optional)
308
"""
309
def __init__(self, matrix: ArrayLike = None, offset: ArrayLike = None,
310
name: str = None): ...
311
312
def apply(self, RGB: ArrayLike, **kwargs) -> NDArray:
313
"""Apply matrix transformation to RGB input."""
314
```
315
316
### LUT File I/O
317
318
Functions for reading and writing LUTs in various industry-standard formats with automatic format detection.
319
320
```python { .api }
321
def read_LUT(path: Union[str, Path], method: str = None, **kwargs) -> Union[LUT1D, LUT3x1D, LUT3D, LUTSequence, LUTOperatorMatrix]:
322
"""
323
Read LUT from file with automatic format detection.
324
325
Parameters:
326
- path: LUT file path
327
- method: reading method, auto-detected from extension if None
328
('Cinespace', 'Iridas Cube', 'Resolve Cube', 'Sony SPI1D', 'Sony SPI3D', 'Sony SPImtx')
329
- **kwargs: additional arguments passed to format-specific readers
330
331
Returns:
332
LUT object (LUT1D, LUT3x1D, LUT3D, LUTSequence, or LUTOperatorMatrix)
333
334
Supported formats:
335
- .cube: Iridas/Resolve Cube format
336
- .spi1d: Sony SPI 1D format
337
- .spi3d: Sony SPI 3D format
338
- .spimtx: Sony SPI Matrix format
339
- .csp: Cinespace format
340
"""
341
342
def write_LUT(LUT: Union[LUT1D, LUT3x1D, LUT3D, LUTSequence, LUTOperatorMatrix],
343
path: Union[str, Path], decimals: int = 7, method: str = None, **kwargs) -> bool:
344
"""
345
Write LUT to file with automatic format detection.
346
347
Parameters:
348
- LUT: LUT object to write
349
- path: output file path
350
- decimals: number of decimal places for formatting
351
- method: writing method, auto-detected from extension if None
352
- **kwargs: additional arguments passed to format-specific writers
353
354
Returns:
355
True if successful
356
"""
357
358
def read_LUT_IridasCube(path: Union[str, Path]) -> Union[LUT1D, LUT3x1D, LUT3D]:
359
"""Read Iridas .cube format LUT file."""
360
361
def write_LUT_IridasCube(LUT: Union[LUT1D, LUT3x1D, LUT3D], path: Union[str, Path],
362
decimals: int = 7) -> bool:
363
"""Write LUT to Iridas .cube format."""
364
365
def read_LUT_ResolveCube(path: Union[str, Path]) -> Union[LUTSequence, LUT3D]:
366
"""Read DaVinci Resolve .cube format with sequence support."""
367
368
def write_LUT_ResolveCube(LUT: Union[LUTSequence, LUT3D], path: Union[str, Path],
369
decimals: int = 7) -> bool:
370
"""Write LUT to DaVinci Resolve .cube format."""
371
372
def read_LUT_SonySPI1D(path: Union[str, Path]) -> LUT1D:
373
"""Read Sony .spi1d format LUT file."""
374
375
def write_LUT_SonySPI1D(LUT: LUT1D, path: Union[str, Path], decimals: int = 7) -> bool:
376
"""Write LUT to Sony .spi1d format."""
377
378
def read_LUT_SonySPI3D(path: Union[str, Path]) -> LUT3D:
379
"""Read Sony .spi3d format LUT file."""
380
381
def write_LUT_SonySPI3D(LUT: LUT3D, path: Union[str, Path], decimals: int = 7) -> bool:
382
"""Write LUT to Sony .spi3d format."""
383
384
def read_LUT_SonySPImtx(path: Union[str, Path]) -> LUTOperatorMatrix:
385
"""Read Sony .spimtx matrix format file."""
386
387
def write_LUT_SonySPImtx(LUT: LUTOperatorMatrix, path: Union[str, Path], decimals: int = 7) -> bool:
388
"""Write LUT to Sony .spimtx matrix format."""
389
390
def read_LUT_Cinespace(path: Union[str, Path]) -> Union[LUT1D, LUT3D]:
391
"""Read Cinespace .csp format LUT file."""
392
393
def write_LUT_Cinespace(LUT: Union[LUT1D, LUT3D], path: Union[str, Path], decimals: int = 7) -> bool:
394
"""Write LUT to Cinespace .csp format."""
395
396
def LUT_to_LUT(LUT: Union[LUT1D, LUT3x1D, LUT3D], LUT_class: Type,
397
force_conversion: bool = False, **kwargs) -> Union[LUT1D, LUT3x1D, LUT3D]:
398
"""
399
Convert between different LUT types.
400
401
Parameters:
402
- LUT: source LUT to convert
403
- LUT_class: target LUT class (LUT1D, LUT3x1D, or LUT3D)
404
- force_conversion: allow potentially lossy conversions
405
- **kwargs: additional arguments for conversion
406
407
Returns:
408
Converted LUT of target class
409
"""
410
```
411
412
### Spectral Data I/O
413
414
Functions for reading and writing spectral data from various file formats including CSV, X-Rite, and specialized spectroscopic formats.
415
416
```python { .api }
417
def read_spectral_data_from_csv_file(path: Union[str, Path], **kwargs) -> Dict[str, NDArray]:
418
"""
419
Read spectral data from CSV file.
420
421
Parameters:
422
- path: CSV file path
423
- **kwargs: arguments passed to numpy.genfromtxt (delimiter, names, etc.)
424
425
Returns:
426
Dictionary with 'wavelength' key and numbered field keys
427
428
Expected CSV format:
429
wavelength, field1, field2, field3, ...
430
390, 0.0415, 0.0368, 0.0955, ...
431
395, 0.1052, 0.0959, 0.2383, ...
432
"""
433
434
def read_sds_from_csv_file(path: Union[str, Path], **kwargs) -> Dict[str, SpectralDistribution]:
435
"""
436
Read spectral distributions from CSV file.
437
438
Parameters:
439
- path: CSV file path
440
- **kwargs: arguments for read_spectral_data_from_csv_file
441
442
Returns:
443
Dictionary mapping field names to SpectralDistribution objects
444
"""
445
446
def write_sds_to_csv_file(sds: Dict[str, SpectralDistribution], path: Union[str, Path],
447
delimiter: str = ",", fields: List[str] = None) -> bool:
448
"""
449
Write spectral distributions to CSV file.
450
451
Parameters:
452
- sds: dictionary of SpectralDistribution objects
453
- path: output CSV file path
454
- delimiter: CSV delimiter character
455
- fields: list of SDS keys to write (all if None)
456
457
Returns:
458
True if successful
459
"""
460
461
def read_sds_from_xrite_file(path: Union[str, Path]) -> Dict[str, SpectralDistribution]:
462
"""
463
Read spectral data from X-Rite format file.
464
465
Parameters:
466
- path: X-Rite file path (.txt format)
467
468
Returns:
469
Dictionary mapping sample names to SpectralDistribution objects
470
471
Notes:
472
Supports X-Rite ColorChecker and similar spectral measurement files
473
"""
474
```
475
476
### IES TM-27-14 Format Support
477
478
Specialized classes and functions for reading/writing IES TM-27-14 spectral distribution files.
479
480
```python { .api }
481
@dataclass
482
class Header_IESTM2714:
483
"""
484
IES TM-27-14 file header specification.
485
486
Attributes:
487
- manufacturer: manufacturer name
488
- catalog_number: catalog/model number
489
- description: description text
490
- document_creator: document creator information
491
- unique_identifier: unique file identifier
492
- measurement_equipment: measurement equipment details
493
- laboratory: laboratory information
494
- report_number: report number
495
- report_date: measurement date
496
- document_creation_date: file creation date
497
- comments: additional comments
498
"""
499
manufacturer: str = ""
500
catalog_number: str = ""
501
description: str = ""
502
document_creator: str = ""
503
unique_identifier: str = ""
504
measurement_equipment: str = ""
505
laboratory: str = ""
506
report_number: str = ""
507
report_date: str = ""
508
document_creation_date: str = ""
509
comments: str = ""
510
511
class SpectralDistribution_IESTM2714(SpectralDistribution):
512
"""
513
SpectralDistribution subclass for IES TM-27-14 format with header support.
514
515
Parameters:
516
- data: spectral data (inherited from SpectralDistribution)
517
- header: Header_IESTM2714 object with metadata
518
"""
519
def __init__(self, data: Union[dict, ArrayLike] = None, domain: ArrayLike = None,
520
header: Header_IESTM2714 = None, **kwargs): ...
521
522
@property
523
def header(self) -> Header_IESTM2714: ...
524
```
525
526
### Device-Specific Spectral Formats
527
528
Support for reading spectral data from specific measurement devices.
529
530
```python { .api }
531
class SpectralDistribution_UPRTek(SpectralDistribution):
532
"""
533
SpectralDistribution subclass for UPRTek device files.
534
535
Specialized for reading spectral data from UPRTek spectrometers
536
with device-specific metadata and calibration information.
537
"""
538
539
class SpectralDistribution_Sekonic(SpectralDistribution):
540
"""
541
SpectralDistribution subclass for Sekonic device files.
542
543
Specialized for reading spectral data from Sekonic spectroradiometers
544
with device-specific metadata and measurement parameters.
545
"""
546
```
547
548
### Spectral Image I/O (Fichet 2021 Format)
549
550
Advanced support for reading and writing spectral images using the OpenEXR layout proposed by Fichet et al. (2021).
551
552
```python { .api }
553
@dataclass
554
class Specification_Fichet2021:
555
"""
556
Specification for Fichet 2021 spectral image format.
557
558
Attributes:
559
- path: file path
560
- components: spectral components data
561
- colourspace: target colourspace for RGB preview
562
- illuminant: illuminant for colourimetric computations
563
- cmfs: colour matching functions
564
- chromatic_adaptation_transform: adaptation method
565
- additional_data: additional metadata
566
"""
567
path: Union[str, Path] = ""
568
components: dict = field(default_factory=dict)
569
colourspace: str = "sRGB"
570
illuminant: Union[str, SpectralDistribution] = "D65"
571
cmfs: Union[str, MultiSpectralDistributions] = "CIE 1931 2 Degree Standard Observer"
572
chromatic_adaptation_transform: str = "CAT02"
573
additional_data: bool = True
574
575
def read_spectral_image_Fichet2021(path: Union[str, Path], **kwargs) -> Specification_Fichet2021:
576
"""
577
Read spectral image in Fichet 2021 OpenEXR format.
578
579
Parameters:
580
- path: path to OpenEXR spectral image file
581
- **kwargs: additional arguments for processing
582
583
Returns:
584
Specification_Fichet2021 object with spectral components and metadata
585
"""
586
587
def write_spectral_image_Fichet2021(specification: Specification_Fichet2021,
588
path: Union[str, Path] = None) -> bool:
589
"""
590
Write spectral image in Fichet 2021 OpenEXR format.
591
592
Parameters:
593
- specification: Specification_Fichet2021 object to write
594
- path: output file path (uses specification.path if None)
595
596
Returns:
597
True if successful
598
"""
599
600
ComponentsFichet2021 = Dict[Union[str, float], Tuple[NDArray, NDArray]]
601
"""Type alias for Fichet 2021 spectral components mapping wavelengths to image data."""
602
603
def sd_to_spectrum_attribute_Fichet2021(sd: SpectralDistribution,
604
colourspace: str = "sRGB") -> str:
605
"""Convert SpectralDistribution to Fichet 2021 spectrum attribute string."""
606
607
def spectrum_attribute_to_sd_Fichet2021(attribute: str) -> SpectralDistribution:
608
"""Convert Fichet 2021 spectrum attribute string to SpectralDistribution."""
609
```
610
611
### Color Transform Language (CTL) Processing
612
613
Support for Academy Color Transformation Language processing for image color transformations.
614
615
```python { .api }
616
def ctl_render(input_image: ArrayLike, csc_in: str, csc_out: str,
617
ctl_transforms: List[str] = None, input_scale: float = 1.0,
618
output_scale: float = 1.0, global_params: dict = None,
619
aces_ctl_directory: Union[str, Path] = None) -> NDArray:
620
"""
621
Render input image through CTL (Color Transform Language) pipeline.
622
623
Parameters:
624
- input_image: input image array
625
- csc_in: input color space conversion
626
- csc_out: output color space conversion
627
- ctl_transforms: list of CTL transform files to apply
628
- input_scale: scaling factor for input
629
- output_scale: scaling factor for output
630
- global_params: global CTL parameters dictionary
631
- aces_ctl_directory: path to ACES CTL transforms directory
632
633
Returns:
634
Processed image array
635
"""
636
637
def process_image_ctl(input_image: ArrayLike, **kwargs) -> NDArray:
638
"""
639
Process image through CTL transforms with simplified interface.
640
641
Parameters:
642
- input_image: input image array
643
- **kwargs: arguments passed to ctl_render
644
645
Returns:
646
Processed image array
647
"""
648
649
def template_ctl_transform_float(input_value: str = "input",
650
output_value: str = "output") -> str:
651
"""Generate CTL template for float transformations."""
652
653
def template_ctl_transform_float3(input_value: str = "input",
654
output_value: str = "output") -> str:
655
"""Generate CTL template for float3 (RGB) transformations."""
656
```
657
658
### OpenColorIO Processing
659
660
Integration with OpenColorIO for color management and transformation pipelines.
661
662
```python { .api }
663
def process_image_OpenColorIO(image: ArrayLike, *args, **kwargs) -> NDArray:
664
"""
665
Process image through OpenColorIO color management pipeline.
666
667
Parameters:
668
- image: input image array
669
- *args: positional arguments for OpenColorIO processing
670
- **kwargs: keyword arguments for OCIO configuration and transforms
671
672
Returns:
673
Color-managed image array
674
675
Notes:
676
Requires OpenColorIO installation and valid OCIO configuration
677
"""
678
```
679
680
### Method Collections and Constants
681
682
Registry mappings for available I/O methods and supported formats.
683
684
```python { .api }
685
READ_IMAGE_METHODS: dict = {
686
"OpenImageIO": read_image_OpenImageIO,
687
"Imageio": read_image_Imageio,
688
}
689
"""Available image reading methods."""
690
691
WRITE_IMAGE_METHODS: dict = {
692
"OpenImageIO": write_image_OpenImageIO,
693
"Imageio": write_image_Imageio,
694
}
695
"""Available image writing methods."""
696
697
LUT_READ_METHODS: dict = {
698
"Cinespace": read_LUT_Cinespace,
699
"Iridas Cube": read_LUT_IridasCube,
700
"Resolve Cube": read_LUT_ResolveCube,
701
"Sony SPI1D": read_LUT_SonySPI1D,
702
"Sony SPI3D": read_LUT_SonySPI3D,
703
"Sony SPImtx": read_LUT_SonySPImtx,
704
}
705
"""Available LUT reading methods mapped to format names."""
706
707
LUT_WRITE_METHODS: dict = {
708
"Cinespace": write_LUT_Cinespace,
709
"Iridas Cube": write_LUT_IridasCube,
710
"Resolve Cube": write_LUT_ResolveCube,
711
"Sony SPI1D": write_LUT_SonySPI1D,
712
"Sony SPI3D": write_LUT_SonySPI3D,
713
"Sony SPImtx": write_LUT_SonySPImtx,
714
}
715
"""Available LUT writing methods mapped to format names."""
716
717
MAPPING_EXTENSION_TO_LUT_FORMAT: dict = {
718
".cube": "Iridas Cube",
719
".spi1d": "Sony SPI1D",
720
".spi3d": "Sony SPI3D",
721
".spimtx": "Sony SPImtx",
722
".csp": "Cinespace",
723
}
724
"""Mapping of file extensions to LUT format names for auto-detection."""
725
726
XRITE_FILE_ENCODING: str = "utf-8"
727
"""Default encoding for X-Rite spectral data files."""
728
```
729
730
## Usage Examples
731
732
### Basic Image I/O
733
734
```python
735
import colour
736
737
# Read an image with automatic format detection
738
image = colour.read_image("input.exr")
739
740
# Process the image (example: apply gamma correction)
741
processed = image ** (1/2.2)
742
743
# Write with specific bit depth
744
colour.write_image(processed, "output.png", bit_depth="uint8")
745
746
# Read with specific backend and attributes
747
image, attributes = colour.read_image_OpenImageIO("input.exr", attributes=True)
748
print(f"Image attributes: {attributes}")
749
```
750
751
### Working with LUTs
752
753
```python
754
# Read a LUT file (format auto-detected from extension)
755
lut = colour.read_LUT("color_correction.cube")
756
757
# Apply LUT to image
758
corrected_image = lut.apply(image)
759
760
# Create a custom 1D LUT
761
import numpy as np
762
gamma_table = np.power(np.linspace(0, 1, 1024), 1/2.2)
763
gamma_lut = colour.LUT1D(gamma_table, name="Gamma 2.2")
764
765
# Apply and save
766
gamma_corrected = gamma_lut.apply(image)
767
colour.write_LUT(gamma_lut, "gamma_correction.spi1d")
768
769
# Create and work with 3D LUTs
770
lut3d = colour.LUT3D(size=33) # Creates linear 33x33x33 LUT
771
lut3d.table = lut3d.table ** (1/2.2) # Apply gamma to each channel
772
colour.write_LUT(lut3d, "gamma_3d.cube")
773
```
774
775
### Spectral Data Processing
776
777
```python
778
# Read spectral data from CSV
779
spectral_data = colour.read_sds_from_csv_file("reflectances.csv")
780
print(f"Available samples: {list(spectral_data.keys())}")
781
782
# Read X-Rite ColorChecker data
783
xrite_data = colour.read_sds_from_xrite_file("colorchecker.txt")
784
785
# Write processed spectral data back to CSV
786
colour.write_sds_to_csv_file(xrite_data, "processed_spectra.csv")
787
788
# Work with IES TM-27-14 format
789
from colour.io import Header_IESTM2714, SpectralDistribution_IESTM2714
790
791
header = Header_IESTM2714(
792
manufacturer="Test Lab",
793
description="Sample measurement",
794
measurement_equipment="Spectrometer Model XYZ"
795
)
796
797
# Create spectral distribution with metadata
798
sd_with_header = SpectralDistribution_IESTM2714(
799
data={380: 0.1, 390: 0.15, 400: 0.2},
800
header=header
801
)
802
```
803
804
### Advanced Spectral Image Processing
805
806
```python
807
# Read Fichet 2021 format spectral image
808
from colour.io import read_spectral_image_Fichet2021
809
810
spec_image = read_spectral_image_Fichet2021("spectral_scene.exr")
811
812
# Access spectral components
813
print(f"Available wavelengths: {list(spec_image.components.keys())}")
814
815
# Convert to RGB for preview
816
rgb_preview = colour.spectral_image_to_RGB(spec_image)
817
colour.write_image(rgb_preview, "preview.png")
818
```
819
820
### Color Management Integration
821
822
```python
823
# Process with OpenColorIO (requires OCIO setup)
824
ocio_processed = colour.process_image_OpenColorIO(
825
image,
826
src="ACES - ACEScg",
827
dst="Output - sRGB"
828
)
829
830
# CTL processing (requires CTL installation)
831
ctl_processed = colour.process_image_ctl(
832
image,
833
csc_in="ACES",
834
csc_out="sRGB",
835
ctl_transforms=["RRT", "ODT.Academy.Rec709_100nits_dim.ctl"]
836
)
837
```
838
839
The I/O system provides comprehensive support for professional color workflows, supporting industry-standard formats and enabling seamless integration with existing pipelines and color management systems.