or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdchromatic-adaptation.mdcolorimetry.mdcolour-appearance.mdcolour-difference.mdcolour-models.mdconstants.mdgeometry.mdindex.mdinput-output.mdmath-utilities.mdnotation.mdplotting.mdquality-assessment.mdtemperature.md

input-output.mddocs/

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.