Our focus with ImageIO is on the IO side of images. If you want to add text to an image or perform any other processing of the image, you will want to bring in an image processing library. Common choices here are scikit-image
or opencv
.
Here is an example of how you can do this using cv2
. Note that I am using a standard image here for better reproducibility, but the same logic works with HDF5 and other video/image formats.
import imageio.v3 as iio
import cv2
frames = iio.imread("imageio:newtonscradle.gif") # example image/frames
# add the text
for frame in frames:
foo = cv2.putText(
frame,
"Hey look some metadata",
(5, 25),
cv2.FONT_HERSHEY_SIMPLEX,
.4,
(0, 0, 0)
)
# write the output
iio.imwrite("annotated.gif", frames, loop=0)
Output:

Weirdly, scikit-image
doesn't allow rendering text onto an image, but there is an age-old issue to track that feature here.
Alternatively, if visualization is what you are after, you could use matplotlib
. This comes with the advantage of giving you all the power of the MPL but comes with the drawback of losing control over individual pixels. This is not ideal for scientific processing (where pixel values matter), but great for quick annotations, human consumption, and qualitative data.
Here is an example how you could recreate the above:
import imageio.v3 as iio
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import figaspect
frames = iio.imread("imageio:newtonscradle.gif")
aspect_ratio = figaspect(frames[0, ..., 0])
annotated_frames = list()
for frame in frames:
fig, ax = plt.subplots(figsize=aspect_ratio, dpi=50)
ax.imshow(frame)
ax.text(5, 5, "Hey look some metadata", fontsize="xx-large", va="top")
ax.set_axis_off()
ax.set_position([0, 0, 1, 1])
fig.canvas.draw()
annotated_frames.append(np.asarray(fig.canvas.renderer.buffer_rgba()))
plt.close(fig)
iio.imwrite("annotated.gif", annotated_frames, loop=0)
Output:
