or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcpp-api.mdfile-io.mdimage-data.mdindex.mdmetadata.md

file-io.mddocs/

0

# File I/O Operations

1

2

Comprehensive file reading and writing operations for EXR images, supporting scanline and tiled formats, multi-part files, and streaming operations with configurable threading.

3

4

## Capabilities

5

6

### Primary File Interface

7

8

The main interface for EXR file operations, providing context management and flexible construction for different use cases.

9

10

```python { .api }

11

class File:

12

def __init__(self, filename: str, separate_channels: bool = False, header_only: bool = False):

13

"""

14

Open existing EXR file for reading.

15

16

Args:

17

filename: Path to EXR file

18

separate_channels: Read channels as separate arrays

19

header_only: Read only header information

20

"""

21

22

def __init__(self, header: dict, channels: dict):

23

"""

24

Create EXR file for writing with single part.

25

26

Args:

27

header: Image metadata and format settings

28

channels: Channel data dictionary

29

"""

30

31

def __init__(self, parts: list):

32

"""

33

Create multi-part EXR file for writing.

34

35

Args:

36

parts: List of Part objects

37

"""

38

39

def __enter__(self):

40

"""Context manager entry."""

41

42

def __exit__(self, *args):

43

"""Context manager exit with cleanup."""

44

45

def header(self, part_index: int = 0) -> dict:

46

"""

47

Get header information for specified part.

48

49

Args:

50

part_index: Part index for multi-part files

51

52

Returns:

53

Header dictionary with metadata

54

"""

55

56

def channels(self, part_index: int = 0) -> dict:

57

"""

58

Get channel data for specified part.

59

60

Args:

61

part_index: Part index for multi-part files

62

63

Returns:

64

Dictionary mapping channel names to Channel objects

65

"""

66

67

def write(self, filename: str) -> None:

68

"""

69

Write EXR data to file.

70

71

Args:

72

filename: Output file path

73

"""

74

75

def width(self) -> int:

76

"""Get image width in pixels."""

77

78

def height(self) -> int:

79

"""Get image height in pixels."""

80

```

81

82

### Part Management

83

84

Individual parts within multi-part EXR files, enabling complex compositing workflows with multiple image layers.

85

86

```python { .api }

87

class Part:

88

def __init__(self, header: dict, channels: dict, name: str):

89

"""

90

Create image part for multi-part files.

91

92

Args:

93

header: Part-specific header information

94

channels: Channel data for this part

95

name: Human-readable part name

96

"""

97

98

def name(self) -> str:

99

"""Get part name."""

100

101

def shape(self) -> tuple:

102

"""Get image dimensions as (height, width)."""

103

104

def width(self) -> int:

105

"""Get image width in pixels."""

106

107

def height(self) -> int:

108

"""Get image height in pixels."""

109

110

def compression(self):

111

"""Get compression method for this part."""

112

113

def type(self):

114

"""Get image type (scanline/tiled/deep)."""

115

116

def typeString(self) -> str:

117

"""Get human-readable image type string."""

118

119

header: dict # Header attributes

120

channels: dict # Channel data mapping

121

part_index: int # Zero-based part index

122

```

123

124

### Channel Representation

125

126

Individual image channels with flexible pixel types and sampling parameters.

127

128

```python { .api }

129

class Channel:

130

def __init__(self, name: str = None, pixels = None, xSampling: int = 1, ySampling: int = 1, pLinear: bool = False):

131

"""

132

Create image channel.

133

134

Args:

135

name: Channel identifier

136

pixels: Pixel data as numpy array

137

xSampling: Horizontal subsampling factor

138

ySampling: Vertical subsampling factor

139

pLinear: Whether pixels are perceptually linear

140

"""

141

142

def pixelType(self):

143

"""Get pixel data type (UINT/HALF/FLOAT)."""

144

145

name: str # Channel name

146

xSampling: int # Horizontal subsampling

147

ySampling: int # Vertical subsampling

148

pLinear: bool # Perceptual linearity flag

149

pixels: numpy.ndarray # Pixel data array

150

```

151

152

## Usage Examples

153

154

### Basic Reading Operations

155

156

```python

157

import OpenEXR

158

import numpy as np

159

160

# Read complete EXR file

161

with OpenEXR.File("input.exr") as infile:

162

header = infile.header()

163

channels = infile.channels()

164

165

# Access specific channels

166

rgb_data = channels["RGB"].pixels

167

alpha_data = channels["A"].pixels if "A" in channels else None

168

169

print(f"Image: {infile.width()}x{infile.height()}")

170

print(f"Channels: {list(channels.keys())}")

171

print(f"Compression: {header['compression']}")

172

173

# Read header only for fast metadata access

174

with OpenEXR.File("input.exr", header_only=True) as infile:

175

header = infile.header()

176

print(f"Image type: {header['type']}")

177

print(f"Data window: {header['dataWindow']}")

178

179

# Read with separate channel arrays

180

with OpenEXR.File("input.exr", separate_channels=True) as infile:

181

channels = infile.channels()

182

r_channel = channels["R"].pixels

183

g_channel = channels["G"].pixels

184

b_channel = channels["B"].pixels

185

```

186

187

### Basic Writing Operations

188

189

```python

190

import OpenEXR

191

import numpy as np

192

193

# Create RGB image data

194

height, width = 1080, 1920

195

rgb_data = np.random.rand(height, width, 3).astype('f')

196

197

# Write single-part file

198

header = {

199

"compression": OpenEXR.ZIP_COMPRESSION,

200

"type": OpenEXR.scanlineimage,

201

"pixelAspectRatio": 1.0

202

}

203

channels = {"RGB": rgb_data}

204

205

with OpenEXR.File(header, channels) as outfile:

206

outfile.write("output.exr")

207

208

# Write separate channels

209

r_data = np.random.rand(height, width).astype('f')

210

g_data = np.random.rand(height, width).astype('f')

211

b_data = np.random.rand(height, width).astype('f')

212

a_data = np.ones((height, width), dtype='f')

213

214

channels = {

215

"R": r_data,

216

"G": g_data,

217

"B": b_data,

218

"A": a_data

219

}

220

221

with OpenEXR.File(header, channels) as outfile:

222

outfile.write("rgba_output.exr")

223

```

224

225

### Multi-Part File Operations

226

227

```python

228

import OpenEXR

229

import numpy as np

230

231

# Create multiple image parts

232

height, width = 1080, 1920

233

234

# Beauty pass

235

beauty_data = np.random.rand(height, width, 3).astype('f')

236

beauty_header = {

237

"compression": OpenEXR.DWAA_COMPRESSION,

238

"type": OpenEXR.scanlineimage

239

}

240

beauty_channels = {"RGB": beauty_data}

241

242

# Depth pass

243

depth_data = np.random.rand(height, width).astype('f')

244

depth_header = {

245

"compression": OpenEXR.ZIP_COMPRESSION,

246

"type": OpenEXR.scanlineimage

247

}

248

depth_channels = {"Z": depth_data}

249

250

# Motion vector pass

251

motion_data = np.random.rand(height, width, 2).astype('f')

252

motion_header = {

253

"compression": OpenEXR.ZIP_COMPRESSION,

254

"type": OpenEXR.scanlineimage

255

}

256

motion_channels = {"motion": motion_data}

257

258

# Create multi-part file

259

parts = [

260

OpenEXR.Part(beauty_header, beauty_channels, "beauty"),

261

OpenEXR.Part(depth_header, depth_channels, "depth"),

262

OpenEXR.Part(motion_header, motion_channels, "motion")

263

]

264

265

with OpenEXR.File(parts) as outfile:

266

outfile.write("multipart_output.exr")

267

268

# Read multi-part file

269

with OpenEXR.File("multipart_output.exr") as infile:

270

# Access different parts

271

beauty_channels = infile.channels(0) # Beauty pass

272

depth_channels = infile.channels(1) # Depth pass

273

motion_channels = infile.channels(2) # Motion pass

274

275

# Get part-specific headers

276

beauty_header = infile.header(0)

277

depth_header = infile.header(1)

278

motion_header = infile.header(2)

279

```

280

281

### High-Performance Streaming

282

283

```python

284

import OpenEXR

285

import numpy as np

286

287

def process_large_exr(input_path, output_path):

288

"""Process large EXR files with memory efficiency."""

289

290

with OpenEXR.File(input_path) as infile:

291

header = infile.header()

292

293

# Modify header for output

294

output_header = header.copy()

295

output_header["compression"] = OpenEXR.DWAA_COMPRESSION

296

297

# Process in chunks for memory efficiency

298

channels = infile.channels()

299

300

# Apply processing to channel data

301

processed_channels = {}

302

for name, channel in channels.items():

303

# Example: gamma correction

304

processed_pixels = np.power(channel.pixels, 1.0/2.2)

305

processed_channels[name] = processed_pixels

306

307

# Write processed result

308

with OpenEXR.File(output_header, processed_channels) as outfile:

309

outfile.write(output_path)

310

311

# Process file

312

process_large_exr("large_input.exr", "processed_output.exr")

313

```

314

315

### Error Handling

316

317

```python

318

import OpenEXR

319

320

def safe_exr_read(filename):

321

"""Safely read EXR file with proper error handling."""

322

323

try:

324

with OpenEXR.File(filename) as infile:

325

header = infile.header()

326

channels = infile.channels()

327

return header, channels

328

329

except IOError as e:

330

print(f"File I/O error: {e}")

331

return None, None

332

333

except Exception as e:

334

print(f"EXR format error: {e}")

335

return None, None

336

337

def safe_exr_write(filename, header, channels):

338

"""Safely write EXR file with validation."""

339

340

# Validate header

341

required_keys = ["compression", "type"]

342

for key in required_keys:

343

if key not in header:

344

raise ValueError(f"Missing required header key: {key}")

345

346

# Validate channels

347

if not channels:

348

raise ValueError("No channels provided")

349

350

try:

351

with OpenEXR.File(header, channels) as outfile:

352

outfile.write(filename)

353

print(f"Successfully wrote: {filename}")

354

355

except Exception as e:

356

print(f"Write error: {e}")

357

raise

358

359

# Usage

360

header, channels = safe_exr_read("input.exr")

361

if header and channels:

362

safe_exr_write("output.exr", header, channels)

363

```