0
# Modern v3 API
1
2
Streamlined interface with context managers, unified resource handling, and enhanced metadata access designed for modern Python development patterns.
3
4
## Capabilities
5
6
### Resource Opening with Context Management
7
8
Open image resources using context managers for automatic cleanup and resource management.
9
10
```python { .api }
11
def imopen(uri, io_mode, *, plugin=None, extension=None, format_hint=None,
12
legacy_mode=False, **kwargs):
13
"""
14
Open an ImageResource with context manager support.
15
16
Parameters:
17
- uri (ImageResource): File path, URL, bytes, or file object
18
- io_mode (str): 'r' for reading, 'w' for writing
19
- plugin (str, optional): Specific plugin to use
20
- extension (str, optional): Treat resource as having this extension
21
- format_hint (str, optional): Deprecated, use extension instead
22
- legacy_mode (bool): Enable v2 compatibility mode
23
- **kwargs: Plugin-specific parameters
24
25
Returns:
26
- PluginV3: Plugin instance for the opened resource
27
28
Warning: Remember to close plugin when not using context manager (PyPy)
29
"""
30
```
31
32
**Usage Examples:**
33
34
```python
35
import imageio.v3 as iio
36
37
# Basic usage with context manager
38
with iio.imopen('image.jpg', 'r') as img_file:
39
image = img_file.read()
40
properties = img_file.properties()
41
metadata = img_file.metadata()
42
print(f"Shape: {properties.shape}")
43
44
# Writing with context manager
45
import numpy as np
46
image = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
47
48
with iio.imopen('output.jpg', 'w') as img_file:
49
img_file.write(image)
50
51
# Specify plugin explicitly
52
with iio.imopen('data.raw', 'r', plugin='RAW-FI') as img_file:
53
raw_data = img_file.read()
54
55
# Manual resource management (ensure cleanup)
56
img_file = iio.imopen('image.png', 'r')
57
try:
58
image = img_file.read()
59
finally:
60
img_file.close()
61
```
62
63
### Modern Image Reading
64
65
Read images with enhanced control and modern Python patterns.
66
67
```python { .api }
68
def imread(uri, *, index=None, plugin=None, extension=None,
69
format_hint=None, **kwargs):
70
"""
71
Read an ndimage from a URI using v3 API.
72
73
Parameters:
74
- uri (ImageResource): Resource to read from
75
- index (int|Ellipsis|None):
76
- int: Select specific image by index
77
- ...: Read all images and stack along batch dimension
78
- None: Let plugin decide (usually first image)
79
- plugin (str, optional): Plugin to use
80
- extension (str, optional): Treat resource as this extension
81
- format_hint (str, optional): Deprecated, use extension
82
- **kwargs: Plugin-specific parameters
83
84
Returns:
85
- np.ndarray: Image data as numpy array
86
"""
87
```
88
89
**Usage Examples:**
90
91
```python
92
import imageio.v3 as iio
93
94
# Basic reading
95
image = iio.imread('photo.jpg')
96
print(f"Shape: {image.shape}, dtype: {image.dtype}")
97
98
# Read specific frame from multi-image file
99
frame_5 = iio.imread('animation.gif', index=5)
100
101
# Read all frames and stack them
102
all_frames = iio.imread('animation.gif', index=...)
103
print(f"Stacked shape: {all_frames.shape}") # (n_frames, height, width, channels)
104
105
# Read with specific plugin
106
image = iio.imread('data.tiff', plugin='tifffile')
107
108
# Read with format hint
109
image = iio.imread('ambiguous_file', extension='.png')
110
```
111
112
### Modern Image Writing
113
114
Write images with unified interface and enhanced control.
115
116
```python { .api }
117
def imwrite(uri, image, *, plugin=None, extension=None,
118
format_hint=None, **kwargs):
119
"""
120
Write an ndimage to the given URI using v3 API.
121
122
Parameters:
123
- uri (ImageResource): Resource to write to
124
- image (ArrayLike): Image data to write
125
- plugin (str, optional): Plugin to use
126
- extension (str, optional): Treat resource as this extension
127
- format_hint (str, optional): Deprecated, use extension
128
- **kwargs: Plugin-specific parameters
129
130
Returns:
131
- None: When writing to file
132
- bytes: When uri is '<bytes>'
133
"""
134
```
135
136
**Usage Examples:**
137
138
```python
139
import imageio.v3 as iio
140
import numpy as np
141
142
# Basic writing
143
image = np.random.randint(0, 255, (200, 300, 3), dtype=np.uint8)
144
iio.imwrite('output.png', image)
145
146
# Write with specific plugin
147
iio.imwrite('output.tiff', image, plugin='tifffile')
148
149
# Write as bytes
150
png_bytes = iio.imwrite('<bytes>', image, extension='.png')
151
152
# Write with quality settings
153
iio.imwrite('high_quality.jpg', image, quality=95)
154
155
# Write multi-dimensional array as stack
156
volume = np.random.randint(0, 255, (10, 100, 100), dtype=np.uint8)
157
iio.imwrite('stack.tiff', volume)
158
```
159
160
### Image Iteration
161
162
Iterate through images in a file with memory-efficient streaming.
163
164
```python { .api }
165
def imiter(uri, *, plugin=None, extension=None, format_hint=None, **kwargs):
166
"""
167
Iterate over ndimages in a URI.
168
169
Parameters:
170
- uri (ImageResource): Resource to iterate over
171
- plugin (str, optional): Plugin to use
172
- extension (str, optional): Treat resource as this extension
173
- format_hint (str, optional): Deprecated, use extension
174
- **kwargs: Plugin-specific parameters
175
176
Yields:
177
- np.ndarray: Next image in the sequence
178
"""
179
```
180
181
**Usage Examples:**
182
183
```python
184
import imageio.v3 as iio
185
186
# Iterate through GIF frames
187
for i, frame in enumerate(iio.imiter('animation.gif')):
188
print(f"Frame {i}: {frame.shape}")
189
# Process frame without loading all frames into memory
190
191
# Iterate through video frames
192
for frame_num, frame in enumerate(iio.imiter('video.mp4')):
193
if frame_num % 30 == 0: # Process every 30th frame
194
processed = process_frame(frame) # Your processing function
195
iio.imwrite(f'frame_{frame_num:06d}.jpg', processed)
196
197
# Iterate with plugin specification
198
for page in iio.imiter('document.pdf', plugin='pillow'):
199
print(f"Page shape: {page.shape}")
200
201
# Process large TIFF stack efficiently
202
total_intensity = 0
203
frame_count = 0
204
for slice_img in iio.imiter('large_stack.tiff'):
205
total_intensity += slice_img.mean()
206
frame_count += 1
207
208
average_intensity = total_intensity / frame_count
209
print(f"Average intensity across {frame_count} slices: {average_intensity}")
210
```
211
212
### Standardized Properties
213
214
Get standardized image properties without loading pixel data.
215
216
```python { .api }
217
def improps(uri, *, index=None, plugin=None, extension=None, **kwargs):
218
"""
219
Read standardized metadata/properties.
220
221
Parameters:
222
- uri (ImageResource): Resource to analyze
223
- index (int|Ellipsis|None): Which image to analyze
224
- plugin (str, optional): Plugin to use
225
- extension (str, optional): Treat resource as this extension
226
- **kwargs: Plugin-specific parameters
227
228
Returns:
229
- ImageProperties: Standardized properties dataclass
230
"""
231
```
232
233
**Usage Examples:**
234
235
```python
236
import imageio.v3 as iio
237
238
# Get properties without loading pixel data
239
props = iio.improps('large_image.tiff')
240
print(f"Shape: {props.shape}")
241
print(f"Data type: {props.dtype}")
242
print(f"Number of images: {props.n_images}")
243
print(f"Is batch: {props.is_batch}")
244
print(f"Spacing: {props.spacing}")
245
246
# Check properties of specific frame
247
props_frame_10 = iio.improps('animation.gif', index=10)
248
249
# Check properties of all frames stacked
250
props_all = iio.improps('animation.gif', index=...)
251
print(f"Stacked shape: {props_all.shape}") # Includes batch dimension
252
253
# Use properties to decide processing strategy
254
if props.n_images > 100:
255
print("Large multi-image file, use iteration")
256
for frame in iio.imiter('large_file.tiff'):
257
process_frame(frame)
258
else:
259
print("Small file, load all at once")
260
images = iio.imread('small_file.tiff', index=...)
261
```
262
263
### Format-Specific Metadata
264
265
Access detailed, format-specific metadata.
266
267
```python { .api }
268
def immeta(uri, *, index=None, plugin=None, extension=None,
269
exclude_applied=True, **kwargs):
270
"""
271
Read format-specific metadata.
272
273
Parameters:
274
- uri (ImageResource): Resource to analyze
275
- index (int|Ellipsis|None): Which image's metadata to read
276
- plugin (str, optional): Plugin to use
277
- extension (str, optional): Treat resource as this extension
278
- exclude_applied (bool): Exclude already-applied transformations
279
- **kwargs: Plugin-specific parameters
280
281
Returns:
282
- dict: Format-specific metadata dictionary
283
"""
284
```
285
286
**Usage Examples:**
287
288
```python
289
import imageio.v3 as iio
290
291
# Get EXIF data from JPEG
292
jpeg_meta = iio.immeta('photo.jpg')
293
print("EXIF data:", jpeg_meta.get('exif', {}))
294
print("Camera make:", jpeg_meta.get('exif', {}).get('Make', 'Unknown'))
295
296
# Get TIFF metadata
297
tiff_meta = iio.immeta('microscopy.tiff')
298
print("TIFF tags:", tiff_meta)
299
print("Resolution:", tiff_meta.get('resolution', 'Unknown'))
300
301
# Get global metadata (index=...)
302
global_meta = iio.immeta('multi_image.tiff', index=...)
303
print("Global metadata:", global_meta)
304
305
# Get metadata for specific frame
306
frame_meta = iio.immeta('animation.gif', index=5)
307
print("Frame 5 metadata:", frame_meta)
308
309
# Include applied transformations in metadata
310
full_meta = iio.immeta('image.jpg', exclude_applied=False)
311
print("Full metadata including applied transforms:", full_meta)
312
```
313
314
## Advanced V3 Features
315
316
### Plugin Selection and Priority
317
318
Control plugin selection explicitly:
319
320
```python
321
import imageio.v3 as iio
322
323
# List available plugins for a format
324
# (Check imageio.config.known_plugins for available options)
325
326
# Force specific plugin usage
327
image = iio.imread('image.tiff', plugin='tifffile') # Use tifffile plugin
328
image = iio.imread('image.tiff', plugin='pillow') # Use pillow plugin
329
330
# Use extension hint to influence plugin selection
331
image = iio.imread('ambiguous_file', extension='.jpg')
332
333
# Modern approach replaces legacy format parameter
334
# Old v2 style: imread('file.jpg', format='JPEG-PIL')
335
# New v3 style: imread('file.jpg', plugin='pillow')
336
```
337
338
### Batch Processing with V3 API
339
340
Efficient batch operations using modern patterns:
341
342
```python
343
import imageio.v3 as iio
344
from pathlib import Path
345
import numpy as np
346
347
def process_images_v3(input_dir, output_dir, operation='grayscale'):
348
"""Process images using v3 API patterns."""
349
input_path = Path(input_dir)
350
output_path = Path(output_dir)
351
output_path.mkdir(exist_ok=True)
352
353
for img_file in input_path.glob('*.jpg'):
354
try:
355
# Check properties first
356
props = iio.improps(img_file)
357
print(f"Processing {img_file.name}: {props.shape}")
358
359
# Read and process
360
image = iio.imread(img_file)
361
362
if operation == 'grayscale' and len(props.shape) == 3:
363
# Convert to grayscale
364
processed = np.mean(image, axis=2).astype(image.dtype)
365
elif operation == 'thumbnail':
366
# Simple downsampling (for demo)
367
processed = image[::4, ::4] # Every 4th pixel
368
else:
369
processed = image
370
371
# Write result
372
output_file = output_path / f"processed_{img_file.name}"
373
iio.imwrite(output_file, processed)
374
375
except Exception as e:
376
print(f"Error processing {img_file.name}: {e}")
377
378
# Usage
379
process_images_v3('input_photos', 'output_photos', 'grayscale')
380
```
381
382
### Error Handling and Diagnostics
383
384
V3 API provides enhanced error information:
385
386
```python
387
import imageio.v3 as iio
388
389
# Comprehensive error handling
390
def safe_image_read(uri):
391
"""Safely read an image with detailed error handling."""
392
try:
393
# First check if we can get properties
394
props = iio.improps(uri)
395
print(f"File properties: {props.shape}, {props.dtype}")
396
397
# Then read the image
398
image = iio.imread(uri)
399
return image, None
400
401
except FileNotFoundError:
402
return None, "File not found"
403
except PermissionError:
404
return None, "Permission denied"
405
except Exception as e:
406
# Check if it's a plugin-specific error
407
error_msg = str(e)
408
if "plugin" in error_msg.lower():
409
return None, f"Plugin error: {error_msg}"
410
else:
411
return None, f"General error: {error_msg}"
412
413
# Usage
414
image, error = safe_image_read('problematic_file.jpg')
415
if error:
416
print(f"Failed to read image: {error}")
417
else:
418
print(f"Successfully read image: {image.shape}")
419
```
420
421
### Context Manager Patterns
422
423
Advanced context manager usage:
424
425
```python
426
import imageio.v3 as iio
427
428
# Process multiple files with shared plugin instance
429
def batch_process_with_context():
430
"""Demonstrate efficient context manager usage."""
431
432
# Reading multiple images with same plugin
433
with iio.imopen('first_image.tiff', 'r', plugin='tifffile') as img_file:
434
props = img_file.properties()
435
print(f"First image: {props.shape}")
436
437
# Plugin instance can read multiple "pages" if supported
438
if hasattr(img_file, 'iter'):
439
for i, page in enumerate(img_file.iter()):
440
print(f"Page {i}: {page.shape}")
441
442
# Writing multiple related files
443
images = [np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
444
for _ in range(3)]
445
446
for i, image in enumerate(images):
447
with iio.imopen(f'output_{i:03d}.png', 'w') as img_file:
448
img_file.write(image)
449
450
# Nested context managers for complex operations
451
def complex_processing():
452
"""Complex processing with multiple resources."""
453
454
with iio.imopen('input.tiff', 'r') as reader:
455
with iio.imopen('output.tiff', 'w') as writer:
456
for page in reader.iter():
457
# Process each page
458
processed = apply_processing(page) # Your processing
459
writer.write(processed)
460
461
batch_process_with_context()
462
```