class ImageIO -- ImageIO 对象

ImageIO 类以 OpenMV 原生的磁盘格式记录和回放 Image 帧流。单个流可以保存异构的帧(不同的像素格式/尺寸),并为每一帧记录帧间间隔,因此回放时会重现原始的帧率。

共有两种后备存储:

  • 文件流 —— 帧从文件系统上的某个文件读取或追加到该文件。文件以一个 16 字节的魔术头 OMV IMG STR Vx.y 开头,后面跟着各帧的数据块。当前的写入器输出 V2.0;较旧的 V1.0V1.1 文件仍可读取。

  • 内存流 —— 帧从构造时分配的固定大小 RAM 缓冲区读取或写入。在需要录制但又不想触及文件系统的滤波器之间往返传递帧时非常有用。

class image.ImageIO(path: str | Tuple[int, int, int], mode: str | int)

创建一个 ImageIO 流。

如果 path 是一个字符串,则在该路径处打开一个文件流。mode 必须为以下之一:

  • 'r' —— 打开一个已有文件以供读取。会校验魔术头并记录版本(V1.0 / V1.1 / V2.0)以供 version() 使用。

  • 'w' —— 截断/创建文件并写入一个全新的 V2.0 魔术头。每次调用 write() 都会追加帧。

如果 path 是一个三元组 (w, h, pixformat),则分配一个内存流。此时 mode 是要预分配的帧槽位数量(整数)。缓冲区按 count(w, h, pixformat) 帧的大小分配,并且在创建后不允许增长pixformatimage.BINARYimage.GRAYSCALEimage.RGB565image.BAYERimage.YUV422image.JPEGimage.PNG 之一。对于压缩格式(image.JPEGimage.PNG),每个槽位的大小按 2 bpp 估算;大于估算值的帧会在 write() 时引发 ValueError

检视

type() int

返回流的后备存储类型:文件流为 FILE_STREAM,内存流为 MEMORY_STREAM

is_closed() bool

如果已对该对象调用过 close(),则返回 True。一旦关闭,流在后续任何读/写/定位操作上都会引发 OSError("Stream closed")

count() int

返回流中当前存储的帧数。对于文件流,该值随着 write() 追加帧而增长;对于内存流,该值在构造时即固定。

offset() int

返回当前帧索引。由 read()write() 递增,由 seek() 重置。

version() int | None

返回文件流的磁盘格式版本(V1.010V1.111V2.020)。对于内存流返回 None

buffer_size() int | None

返回内存流中每个槽位的像素缓冲区大小(字节),即槽位大小减去内部 Image 记账头。对于文件流返回 None。将其与 count() 配合使用,以检查某个特定帧尺寸是否能放下。

size() int

返回流所占用的总字节数 —— 对于文件流是磁盘上的文件大小,对于内存流是完整的 RAM 缓冲区大小(count * per_slot_size,含每个槽位的头部)。

I/O

write(img: Image) ImageIO

追加(文件流)或在偏移处存储(内存流)img,并将 offset() 前进一位。

对于文件流,文件随着帧的追加而增长。在非末尾偏移处写入会截断文件的其余部分,因此帧数可能会缩减。

对于内存流,帧会被写入当前槽位;写入超过最后一个槽位会引发 EOFError("End of stream"),写入大于 buffer_size() 的帧会引发 ValueError("Invalid frame size")

返回 self,因此调用可以链式串联。

read(copy_to_fb: bool = True, *, loop: bool = True, pause: bool = True) Image | None

读取当前 offset() 处的帧,将偏移前进,并返回新的 Image。与 write() 的回放对应部分相对应。

copy_to_fb —— 当为 True(默认)时,解码后的帧会被放入摄像头帧缓冲区(与 csi.CSI.snapshot() 落点相同),因此返回的 Image 可通过 IDE 预览绘制。当为 False 时,帧改为在 MicroPython 堆上分配。

loop(仅限文件流)—— 当为 True(默认)时,读取超过最后一帧会定位回第一帧并继续。当为 False 时,一旦到达文件末尾,调用返回 None

pause —— 当为 True(默认)时,调用会阻塞,直到原始记录的帧间间隔过去为止,从而以记录的原生帧率进行回放。设为 False 可实现尽可能快的回放。

seek(offset: int) ImageIO

offset() 移动到第 offset 帧。offset 必须为非负;内存流的偏移还必须小于 count()

由于帧数据块是可变大小的,文件流的定位会从头开始逐帧遍历文件 —— 对于大跨度跳转,预计耗时为 O(offset)。

返回 self,因此调用可以链式串联。

sync() ImageIO

对于文件流,将待写入数据刷新到磁盘(调用底层文件系统的 sync)。对内存流为空操作。

返回 self,因此调用可以链式串联。

close() None

关闭流。释放内存缓冲区(内存流)或关闭文件(文件流)。在 close() 之后,ImageIO 对象不能再被复用;后续操作会引发 OSError("Stream closed")。两次调用 close() 为空操作。

ImageIO 被垃圾回收时也会自动关闭(它在构造时注册了一个终结器)。

常量

FILE_STREAM: int

对于文件后备的流,type() 返回的值。

MEMORY_STREAM: int

对于内存中的流,type() 返回的值。