第13章 显示画面
第十三章 显示画面
1. 导入
K230 配备 1 路 MIPI-DSI(1x4 lane),可驱动 MIPI 屏幕或通过接口芯片转换驱动 HDMI 显示器。此外,为了方便调试,还支持虚拟显示器,用户可以选择 VIRT
输出设备,即使没有 HDMI 显示器或 LCD 屏幕, 也可在 CanMV-IDE K230
中进行图像预览。
简单来说,用IDE的帧缓冲区来显示成本最低,但受限于USB传输速率,他的帧率和画面质量是不可兼得的,不过简单使用绝对是没问题的。
2. Display模块基础配置
2.1 init方法
初始化 Display 通路,包括 VO 模块、 DSI 模块和 LCD/HDMI。
必须在 MediaManager.init()之前调用
init(type=None, width=None, height=None, osd_num=1, to_ide=False, fps=None, quality=90)
2.1.1 参数
参数名称 | 描述 | 输入 / 输出 | 说明 |
---|---|---|---|
type | 显示设备类型 | 输入 | 必选 |
width | 分辨率宽度 | 输入 | 默认值根据 type 决定 |
height | 分辨率高度 | 输入 | 默认值根据 type 决定 |
osd_num | 在 show_imag 时支持的 LAYER 数量 | 输入 | 越大占用内存越多 |
to_ide | 是否将屏幕显示传输到 IDE 显示 | 输入 | 开启时占用更多内存 |
fps | 显示帧率 | 输入 | 仅支持 VIRT 类型 |
quality | 设置 Jpeg 压缩质量 |
输入 | 仅在 to_ide=True 时有效,范围 [10-100] |
2.2 show_image方法
在屏幕上显示图像。
show_image(img, x=0, y=0, layer=None, alpha=255, flag=0)
2.2.1 参数
参数名称 | 描述 | 输入 / 输出 | 说明 |
---|---|---|---|
img | 显示的图像 | 输入 | |
x | 起始坐标的 x 值 | 输入 | |
y | 起始坐标的 y 值 | 输入 | |
layer | 显示到指定层 | 输入 | 仅支持 OSD 层,若需要多层请在init中设置 osd_num |
alpha | 图层混合 alpha | 输入 | |
flag | 显示 | 输入 |
2.3 deinit方法
执行反初始化, deinit 方法会关闭整个 Display 通路,包括 VO 模块、 DSI 模块和 LCD/HDMI。
必须在 MediaManager.deinit()之前调用
必须在 sensor.stop()之后调用
deinit()
2.4 bind_layer方法
将 sensor
或 vdec
模块的输出绑定到屏幕显示。无需用户手动干预即可持续显示图像。
必须在 init 之前调用
bind_layer(src=(mod, dev, layer), dstlayer, rect=(x, y, w, h), pix_format, alpha, flag)
2.4.1 参数
参数名称 | 描述 | 输入 / 输出 | 说明 |
---|---|---|---|
src | sensor 或 vdec 的输出信息 |
输入 | 可通过 sensor.bind_info() 获取 |
dstlayer | 绑定到 Display 的 显示层 | 输入 | 可绑定到 video 或 osd 层 |
rect | 显示区域 | 输入 | 可通过 sensor.bind_info() 获取 |
pix_format | 图像像素格式 | 输入 | 可通过 sensor.bind_info() 获取 |
alpha | 图层混合 alpha | 输入 | |
flag | 显示 标志 | 输入 | LAYER_VIDEO1 不支持 |
2.5 数据结构描述
2.5.1 type
类型 | 分辨率 (width x height @ fps) |
备注 |
---|---|---|
LT9611 | 1920x1080@30 | 默认值 |
1280x720@30 | ||
640x480@60 | ||
ST7701 | 800x480@30 | 默认值 可设置为竖屏 480x800 |
854x480@30 | 可设置为竖屏 480x854 | |
VIRT | 640x480@90 | 默认值 |
IDE 调试专用,不在外接屏幕上显示内容用户可自定义设置分辨率 (64x64)-(4096x4096) 和帧率 (1-200) |
2.5.2 layer
K230 提供 2 层视频图层支持和 4 层 OSD 图层支持。分列如下:
显示层 | 说明 | 备注 |
---|---|---|
LAYER_VIDEO1 | 仅可在bind_layer中使用 | |
LAYER_VIDEO2 | 仅可在bind_layer中使用 | |
LAYER_OSD0 | 支持 show_image和bind_layer使用 | |
LAYER_OSD1 | 支持show_image和 bind_layer使用 | |
LAYER_OSD2 | 支持 show_image和 bind_layer使用 | |
LAYER_OSD3 | 支持 show_image和 bind_layer使用 |
2.5.3 flag
标志 | 说明 | 备注 |
---|---|---|
FLAG_ROTATION_0 | 旋转 0 度 |
|
FLAG_ROTATION_90 | 旋转 90 度 |
|
FLAG_ROTATION_180 | 旋转 180 度 |
|
FLAG_ROTATION_270 | 旋转 270 度 |
|
FLAG_MIRROR_NONE | 不镜像 | |
FLAG_MIRROR_HOR | 水平镜像 | |
FLAG_MIRROR_VER | 垂直镜像 | |
FLAG_MIRROR_BOTH | 水平与垂直镜像 |
3. 在三种设备上显示图像示例
import time, os, urandom, sys
from media.display import *
from media.media import *
# 显示模式选择
display_mode = "VIRT" # VIRT:IDE LCD:LCD屏幕 HDMI:通过HDMI连接
# 根据显示模式调整显示宽高
if display_mode == "VIRT":
display_width = ALIGN_UP(1920, 16) # 如果没有定义,改为math.ceil
display_height = 1080
elif display_mode == "LCD":
display_width = 800
display_height = 480
elif display_mode == "HDMI":
display_width = 1920
display_height = 1080
else:
raise Exception("Invalid display mode")
# 显示测试函数
def display_test():
print(f"当前模式为{display_mode}")
img = image.Image(display_width, display_height, image.ARGB8888)
if display_mode == "VIRT":
Display.init(Display.VIRT, width=display_width, height=display_height, fps=60)
elif display_mode == "LCD":
Display.init(Display.ST7701, width=display_width, height=display_height, to_ide=True)
elif display_mode == "HDMI":
Display.init(Display.LT9611, width=display_width, height=display_height, to_ide=True)
MediaManager.init() # 初始化媒体管理器
try:
while True:
img.clear() # 清除
for i in range(10):
# 随机生成字符串位置、颜色、大小
x = (urandom.getrandbits(11) % img.width()) # 随机X坐标
y = (urandom.getrandbits(11) % img.height()) # 随机Y坐标
r = urandom.getrandbits(8)
g = urandom.getrandbits(8)
b = urandom.getrandbits(8)
size = (urandom.getrandbits(30) % 64) + 32 # 字体大小32到96之间
# 绘制字符串
img.draw_string_advanced(x, y, size, "Hello, K230, 显示图画测试", color=(r, g, b))
Display.show_image(img)
time.sleep(1)
except KeyboardInterrupt as e:
print("用户终止:", e) # 捕获键盘中断异常
except BaseException as e:
print(f"异常:{e}") # 捕获其他异常
finally:
# 清理资源
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP) # 启用睡眠模式的退出点
time.sleep_ms(100)
MediaManager.deinit()
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE) # 启用退出点
display_test() # 调用显示测试函数
本文作者:hazy1k
本文链接:https://www.cnblogs.com/hazy1k/p/18711483
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步