Of course! The term imreadmulti is not a standard function in the core Python libraries (like the standard PIL/Pillow or scikit-image). However, it is a very common name for a function that users need to write or that exists in specialized toolkits.

The goal of an imreadmulti function is to read all images from a multi-page file format (like TIFF or GIF) or all images from a series of similarly named files (like image_001.png, image_002.png, etc.).
Here’s a complete guide covering the different scenarios and how to implement the functionality, from the most common methods to writing your own custom function.
The Most Common Case: Reading Multi-Page TIFF Files
The most frequent use case for "imreadmulti" is reading a TIFF file that contains multiple images (or frames) in a single file. For this, the best library is imageio.
Solution using imageio
imageio is a powerful library for reading and writing a wide range of image data, including multi-page formats.

Installation:
pip install imageio
Code:
import imageio
import matplotlib.pyplot as plt
# Path to your multi-page TIFF file
# You can create one for testing with: imageio.mimwrite('test_multi.tif', [image1, image2, image3])
file_path = 'path/to/your/multi_image.tif'
try:
# imageio.imread() is deprecated, use imageio.mimread() for multi-page images
images = imageio.mimread(file_path)
print(f"Successfully read {len(images)} images from '{file_path}'")
print(f"Shape of the first image: {images[0].shape}")
# Let's display the first and second frames
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(images[0])
plt.title("Frame 1")
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(images[1])
plt.title("Frame 2")
plt.axis('off')
plt.tight_layout()
plt.show()
except FileNotFoundError:
print(f"Error: The file '{file_path}' was not found.")
except Exception as e:
print(f"An error occurred: {e}")
Explanation:
imageio.mimread()is the key function. It automatically detects if a file is multi-page and reads all the frames into a Python list.- The
imagesvariable becomes a list of NumPy arrays, where each array is one frame of the multi-page image.
Alternative: Reading Multi-Page TIFF with tifffile
The tifffile library is a highly optimized library specifically for TIFF files. It's often faster and more feature-rich for TIFFs than imageio.

Installation:
pip install tifffile
Code:
import tifffile
import matplotlib.pyplot as plt
file_path = 'path/to/your/multi_image.tif'
try:
# tifffile.imread() can read all pages by default
images = tifffile.imread(file_path)
print(f"Successfully read {len(images)} images from '{file_path}'")
print(f"Shape of the image stack: {images.shape}") # Will be (num_frames, height, width)
# Display the first frame
plt.imshow(images[0])
plt.title("First Frame from tifffile")
plt.axis('off')
plt.show()
except FileNotFoundError:
print(f"Error: The file '{file_path}' was not found.")
except Exception as e:
print(f"An error occurred: {e}")
Explanation:
tifffile.imread()is incredibly simple. If the TIFF file has multiple pages, it returns a NumPy array with an extra dimension for the frames (e.g.,(frames, height, width, channels)).- This is often more convenient for processing, as you don't have to index a list.
Case: Reading a Series of Single Files (e.g., img_001.png)
Sometimes, "imreadmulti" refers to loading a sequence of images that are individual files, often named with a numbering scheme (e.g., from a video or a microscope scan).
Solution using glob and Pillow (PIL)
The glob module is perfect for finding files that match a specific pattern, and Pillow is the standard for basic image manipulation in Python.
Installation:
pip install Pillow
Code:
import glob
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
# Create a list of file paths using a glob pattern
# This pattern looks for all .png files starting with 'image_' and ending with '_###.png'
file_pattern = 'path/to/your/images/image_*.png'
file_paths = sorted(glob.glob(file_pattern))
print(f"Found {len(file_paths)} image files.")
if not file_paths:
print("No files found matching the pattern.")
else:
# Read all images into a list
images = [Image.open(f) for f in file_paths]
# If you need them as NumPy arrays:
image_arrays = [np.array(img) for img in images]
print(f"Shape of the first image array: {image_arrays[0].shape}")
# Display the first image from the sequence
plt.imshow(image_arrays[0])
plt.title(f"First Image: {file_paths[0]}")
plt.axis('off')
plt.show()
Explanation:
glob.glob(file_pattern)finds all files that match the pattern. Usingsorted()is crucial to ensure the images are loaded in the correct order.- We use a list comprehension
[Image.open(f) for f in file_paths]to efficiently open all the files. - Converting them to NumPy arrays with
np.array()is a common next step for analysis.
Creating Your Own imreadmulti Function
You can easily wrap the logic from above into a single, reusable function. This is great for making your code cleaner.
Here is a robust function that tries different methods:
import numpy as np
import glob
import os
from typing import Union, List
def imreadmulti(
source: str,
as_numpy: bool = True,
sort: bool = True
) -> Union[List[Image.Image], List[np.ndarray]]:
"""
Reads multiple images from a multi-page file or a series of single files.
Args:
source (str): The path to a multi-page image file (e.g., .tiff, .gif)
or a directory/glob pattern for a series of images.
as_numpy (bool): If True, returns images as NumPy arrays. Otherwise,
returns them as PIL Image objects. Defaults to True.
sort (bool): If True, sorts the file paths lexicographically before reading.
Defaults to True.
Returns:
A list of image objects (either NumPy arrays or PIL Images).
"""
images = []
# Case 1: Source is a file (try to read as multi-page)
if os.path.isfile(source):
try:
# Try with tifffile first (fast and specific)
import tifffile
images = tifffile.imread(source)
# tifffile returns a numpy array, so we might need to convert to list
if images.ndim > 3 or (images.ndim == 3 and images.shape[0] < 10 and images.shape[1] > 100):
# Heuristic: if it looks like (frames, h, w), convert to list of frames
images = [images[i, ...] for i in range(images.shape[0])]
elif images.ndim == 2: # Single page tiff
images = [images]
print(f"Successfully read {len(images)} frames using tifffile.")
return images if as_numpy else [Image.fromarray(img) for img in images]
except ImportError:
print("tifffile not found, trying imageio...")
try:
# Fallback to imageio
import imageio
images = imageio.mimread(source)
print(f"Successfully read {len(images)} frames using imageio.")
return images if as_numpy else [Image.fromarray(img) for img in images]
except Exception as e:
print(f"Could not read multi-page file '{source}': {e}")
return [] # Return empty list on failure
# Case 2: Source is a glob pattern or directory
elif os.path.isdir(source) or '*' in source or '?' in source:
if os.path.isdir(source):
# If it's a directory, assume all files are images
file_pattern = os.path.join(source, '*')
else:
file_pattern = source
file_paths = glob.glob(file_pattern)
if sort:
file_paths.sort()
if not file_paths:
print(f"No files found for pattern: '{file_pattern}'")
return []
for f_path in file_paths:
try:
img = Image.open(f_path)
if as_numpy:
images.append(np.array(img))
else:
images.append(img)
except Exception as e:
print(f"Could not read image '{f_path}': {e}")
print(f"Successfully read {len(images)} images from a sequence.")
return images
else:
print(f"Error: Source '{source}' is not a valid file or directory/glob pattern.")
return []
# --- Example Usage ---
# Example 1: Using a multi-page TIFF (assuming you have one)
# First, let's create a dummy multi-page tiff for the example to run
try:
import imageio
img1 = np.zeros((100, 100, 3), dtype=np.uint8)
img2 = np.ones((100, 100, 3), dtype=np.uint8) * 128
img3 = np.full((100, 100, 3), 255, dtype=np.uint8)
imageio.mimwrite('my_multipage.tif', [img1, img2, img3])
print("Created dummy 'my_multipage.tif' for demonstration.\n")
# Now use the function
multi_page_images = imreadmulti('my_multipage.tif')
print(f"Loaded {len(multi_page_images)} frames from TIFF.\n")
except ImportError:
print("imageio not installed, skipping TIFF creation/example.\n")
# Example 2: Using a series of PNG files
# Create dummy files for the example
for i in range(3):
img = Image.fromarray(np.random.randint(0, 255, (50, 50, 3), dtype=np.uint8))
img.save(f'series_image_{i:03d}.png')
print("Created dummy 'series_image_*.png' files for demonstration.\n")
# Now use the function
sequence_images = imreadmulti('series_image_*.png')
print(f"Loaded {len(sequence_images)} images from a sequence.")
print(f"Shape of the first image in the sequence: {sequence_images[0].shape}")
# Clean up dummy files
os.remove('my_multipage.tif')
for i in range(3):
os.remove(f'series_image_{i:03d}.png')
Summary: Which one should you use?
| Scenario | Recommended Library | Why? |
|---|---|---|
| Multi-Page TIFF | tifffile |
Fastest, most feature-rich, and idiomatic for TIFF files. Returns a convenient N-d array. |
| Multi-Page TIFF | imageio |
Excellent alternative, supports more formats than just TIFF (e.g., GIF, DICOM). Very easy to use. |
| Image Sequence | glob + Pillow |
Standard, robust, and flexible. Works for any image format supported by Pillow. |
| Custom Function | Wrap one of the above | For cleaner code and handling different input types (file vs. sequence) in one place. |
