
什么是 CanMV K230?
CanMV K230是一款高性价比的RISC-V边缘AI平台,凭借低功耗、强视觉处理能力和开放的开发生态,成为嵌入式AI开发的理想选择,尤其适合需要快速部署视觉与AI功能的创客、中小企业及教育场景。CanMV 是一套 AI 视觉开发平台,K230 是其核心芯片。该模块结合了图像采集、AI推理、边缘计算等能力,适合嵌入式视觉应用开发。
CanMV:类似 OpenMV 的图像处理框架,支持 Python 编程,简化视觉识别开发流程。
K230 芯片:嘉楠科技推出的 AIoT SoC,采用 RISC-V 架构,内置第三代 KPU(AI加速单元),算力高达 6 TOPS,性能是 K210 的 13.7 倍。

绘制文字的draw_string_advanced方法
【推荐使用】
draw_string_advanced
增强版 draw_string,支持中文显示,并允许用户通过 font 参数自定义字体。
image.draw_string_advanced(x, y, char_size, str, [color, font])
【不推荐使用】
draw_string
image.draw_string(x, y, text[, color[, scale=1[, x_spacing=0[, y_spacing=0[, mono_space=True]]]]])
从图像的 (x, y) 位置开始绘制 8x10 大小的文本。参数可以分别传入 x, y,也可以作为元组 (x, y) 一起传递。
text: 要绘制的字符串,换行符 \n、\r 或 \r\n 用于将光标移动到下一行。
color: 表示颜色的 RGB888 元组,适用于灰度或 RGB565 图像,默认为白色。对于灰度图像,还可以传递像素值(范围 0-255);对于 RGB565 图像,可以传递字节翻转的 RGB565 值。
scale: 控制文本的缩放比例,默认为 1。只能为整数。
x_spacing: 调整字符之间的水平间距。正值表示增加间距,负值表示减少。
y_spacing: 调整行之间的垂直间距。正值表示增加间距,负值表示减少。
mono_space: 默认为 True,使字符具有固定宽度。设置为 False 时,字符间距将根据字符宽度动态调整。
该方法返回图像对象,允许通过链式调用其他方法。
不支持压缩图像和 Bayer 格式图像。
项目测试实验代码
#【花雕动手做】CanMV K230 AI视觉识别模块之使用draw_string_advanced()方法绘制文字
# Import required modules
# 导入所需的模块
import time, os, urandom, sys, math
# Import display and media related modules
# 导入显示和媒体相关模块
from media.display import *
from media.media import *
# Define display resolution constants
# 定义显示分辨率常量
DISPLAY_WIDTH = 640 # 显示宽度:640像素
DISPLAY_HEIGHT = 480 # 显示高度:480像素
def display_test():
"""
Function to test display functionality
测试显示功能的函数
主要功能:在屏幕上绘制中文、英文和数字文字,展示多语言文字显示能力
"""
# Create main background image with white color
# 创建白色背景的主图像
# ARGB8888格式:每个像素32位(Alpha透明通道+RGB各8位),支持1600万色和透明度
img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
img.clear() # 清空图像缓冲区,将所有像素设置为透明黑色
# 绘制白色填充矩形作为背景,fill=True表示填充整个区域
img.draw_rectangle(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color=(255,255,255), fill=True)
# Initialize display with ST7701 driver
# 使用ST7701驱动初始化显示器
# ST7701是常见的LCD屏幕驱动芯片,支持RGB接口
# to_ide=True表示将显示输出同时发送到IDE和硬件屏幕,便于调试
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
# Initialize media manager
# 初始化媒体管理器 - 负责统一管理摄像头、显示、音频等媒体资源
MediaManager.init()
try:
# ========== 第一行:中文文字绘制 ==========
# 使用draw_string_advanced方法绘制中文文字"世界你好!"
# 参数说明:
# 245, 200: 文字起始坐标(x, y)
# 30: 字体大小(像素高度),30像素是比较大的字号
# "世界你好!": 要绘制的中文字符串,包含4个汉字和1个标点
# color=(0, 255, 127): 翠绿色,RGB值 (红=0, 绿=255, 蓝=127)
img.draw_string_advanced(245, 200, 30, "世界你好!", color=(0, 255, 127))
# ========== 第二行:英文文字绘制 ==========
# 绘制英文文字"Hello World!",位于中文文字上方
# 参数说明:
# 230, 150: 文字起始坐标,y坐标150比中文的200更靠上
# 30: 字体大小,与中文保持一致
# "Hello World!": 经典的编程问候语
# color=(0, 0, 255): 纯蓝色,RGB值 (红=0, 绿=0, 蓝=255)
img.draw_string_advanced(230, 150, 30, "Hello World!", color=(0, 0, 255))
# ========== 第三行:数字文字绘制 ==========
# 绘制数字序列"1234567890",位于中文文字下方
# 参数说明:
# 230, 260: 文字起始坐标,y坐标260比中文的200更靠下
# 30: 字体大小,保持统一
# "1234567890": 数字0-9的完整序列
# color=(255, 0, 0): 纯红色,RGB值 (红=255, 绿=0, 蓝=0)
img.draw_string_advanced(230, 260, 30, "1234567890", color=(255, 0, 0))
# Update display with background image
# 更新显示背景图像 - 将绘制好的文字图像显示在屏幕上
# 这里使用了双缓冲技术:先在内存中绘制完成,再一次性显示到屏幕,避免闪烁
Display.show_image(img)
# 主循环保持显示
# 无限循环确保程序持续运行,文字保持显示状态
while True:
time.sleep(2) # 每2秒循环一次,保持程序运行,减少CPU占用
except KeyboardInterrupt as e:
# 捕获键盘中断(如用户在终端按Ctrl+C),优雅退出程序
print("user stop: ", e)
except BaseException as e:
# 捕获其他所有异常,防止程序因未处理异常而崩溃
# 这对于嵌入式系统特别重要,确保系统稳定性
print(f"Exception {e}")
# Cleanup and deinitialize display
# 清理并反初始化显示器(由于上面的无限循环,实际不会执行到这里)
Display.deinit()
# 启用睡眠退出点,允许系统进入低功耗模式
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100) # 短暂延时100毫秒,确保硬件资源完全释放
# Release media resources
# 释放媒体资源,包括显示缓冲区和相关硬件资源
MediaManager.deinit()
if __name__ == "__main__":
# Enable exit points and run display test
# 启用退出点并运行显示测试
# EXITPOINT_ENABLE允许通过IDE停止程序执行,提供调试支持
os.exitpoint(os.EXITPOINT_ENABLE)
display_test() # 调用显示测试函数,程序从这里开始执行解读这段CanMV K230文字绘制代码的技术细节和实现原理:
整体架构分析
1. 模块化设计
python
# 核心模块导入
from media.display import * # 显示功能
from media.media import * # 媒体管理
模块分工明确:display负责图形显示,media负责资源管理
硬件抽象层:通过统一的API屏蔽底层硬件差异
核心技术深度解析
1. 显示系统初始化流程
python
# 图像缓冲区创建
img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
# 显示驱动初始化
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
# 媒体管理器初始化
MediaManager.init()
技术要点分析:
ARGB8888格式详解:
text
每个像素32位分配:
A (Alpha) [31:24] - 透明度通道 (本例中未使用,全为0xFF)
R (Red) [23:16] - 红色通道 (0-255)
G (Green) [15:8] - 绿色通道 (0-255)
B (Blue) [7:0] - 蓝色通道 (0-255)
内存布局:0xAARRGGBB
示例:白色 = 0xFFFFFFFF,红色 = 0xFFFF0000
ST7701驱动特性:
RGB接口:并行RGB 16/18/24位接口
分辨率支持:最高支持1280x800
硬件加速:可能包含2D图形加速功能
2. draw_string_advanced() 方法技术实现
方法签名推测:
python
def draw_string_advanced(x, y, size, text, color,
font=None, background=None,
spacing=1, monospace=False):
"""
高级文字绘制方法完整参数
"""
底层渲染算法:
c
// 基于FreeType或类似字体引擎的实现
typedef struct {
uint16_t x;
uint16_t y;
uint8_t size;
char* text;
uint32_t color;
Font* font;
} TextRenderParams;
void draw_string_advanced(TextRenderParams* params) {
// 1. 字体加载和缩放
Font* font = load_font(params->font, params->size);
// 2. 文本编码转换
uint32_t* unicode_chars = text_to_unicode(params->text);
// 3. 逐个字符渲染
uint16_t cursor_x = params->x;
for(int i = 0; unicode_chars[i] != 0; i++) {
// 获取字符位图
CharBitmap* bitmap = get_char_bitmap(font, unicode_chars[i]);
// 4. 位图渲染到帧缓冲区
render_char_bitmap(cursor_x, params->y, bitmap, params->color);
// 5. 更新光标位置(考虑字符宽度和间距)
cursor_x += bitmap->advance + params->spacing;
}
}
3. 多语言文字处理技术
字符编码处理:
python
def handle_multi_language_text(text):
"""
处理多语言文本的编码和渲染
"""
# 编码检测
if is_ascii_text(text):
# ASCII文本(英文、数字、符号)
encoding = 'ascii'
font_file = 'latin_font.bin'
elif contains_chinese(text):
# 中文字符检测
encoding = 'gb2312' # 或UTF-8
font_file = 'chinese_font.bin'
else:
# 其他语言
encoding = 'utf-8'
font_file = 'unicode_font.bin'
return encoding, font_file
中文字符渲染优化:
python
def render_chinese_character(char, size):
"""
中文字符的特殊处理
"""
# 中文字符特点:
# - 字形复杂,笔画多
# - 在点阵字体中需要更高分辨率
# - 可能需要矢量轮廓渲染
if size < 20:
# 小字号使用简化字型
use_simplified_glyph = True
antialias = False
else:
# 大字号使用完整字型,启用抗锯齿
use_simplified_glyph = False
antialias = True
return load_chinese_glyph(char, size, use_simplified_glyph, antialias)
4. 坐标系统和布局算法
文字位置计算:
python
def calculate_text_position(text, size, alignment='center'):
"""
计算文字在屏幕上的位置
"""
# 估算文本宽度(近似计算)
if is_chinese_text(text):
char_width = size * 0.8 # 中文字符宽度系数
else:
char_width = size * 0.6 # 英文字符宽度系数
text_width = len(text) * char_width
# 根据对齐方式计算起始x坐标
if alignment == 'center':
x = (DISPLAY_WIDTH - text_width) // 2
elif alignment == 'left':
x = 10 # 左边距
else: # right
x = DISPLAY_WIDTH - text_width - 10
return x
实际坐标分析:
python
# 代码中的坐标布局:
英文: (230, 150) - "Hello World!" ≈ 240像素宽,居中:230+120=350(接近320)
中文: (245, 200) - "世界你好!" ≈ 125像素宽,居中:245+62.5=307.5(接近320)
数字: (230, 260) - "1234567890" ≈ 180像素宽,居中:230+90=320(完美居中)
# 垂直间距:50像素,形成清晰的视觉层次
5. 颜色管理和视觉设计
颜色空间处理:
python
def color_management_system():
"""
颜色管理和转换
"""
# RGB888转RGB565(如果显示硬件需要)
def rgb888_to_rgb565(r, g, b):
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
# 伽马校正(可选)
def gamma_correct(color):
# 提高在LCD上的显示效果
return int(pow(color / 255.0, 2.2) * 255)
色彩心理学应用:
python
颜色策略 = {
"英文": (0, 0, 255), # 蓝色 - 技术、专业、稳定
"中文": (0, 255, 127), # 翠绿 - 自然、和谐、生机
"数字": (255, 0, 0) # 红色 - 重要、警示、突出
}
6. 性能优化技术
字体缓存机制:
python
class FontCache:
def __init__(self):
self.cache = {}
self.max_size = 100 # 最大缓存字符数
def get_char(self, char, size):
key = (char, size)
if key in self.cache:
return self.cache[key]
# 缓存未命中,加载字符
bitmap = load_char_from_flash(char, size)
# LRU缓存管理
if len(self.cache) >= self.max_size:
self.evict_oldest()
self.cache[key] = bitmap
return bitmap
双缓冲显示技术:
python
def double_buffering_system():
"""
双缓冲显示,避免闪烁
"""
# 前台缓冲区:当前显示的内容
# 后台缓冲区:正在绘制的内容
while True:
# 在后台缓冲区绘制
back_buffer.clear()
back_buffer.draw_text(...)
# 交换缓冲区(原子操作)
swap_buffers()
7. 异常处理和鲁棒性
资源管理:
python
def safe_resource_management():
try:
# 资源申请
display = Display.init(...)
media = MediaManager.init()
# 业务逻辑
main_loop()
finally:
# 确保资源释放(RAII模式)
if display:
Display.deinit()
if media:
MediaManager.deinit()
字体回退机制:
python
def robust_text_rendering(text, size, color):
"""
健壮的文字渲染,处理字体缺失等情况
"""
try:
img.draw_string_advanced(x, y, size, text, color)
except FontNotFoundError:
# 字体缺失,使用默认字体
img.draw_string_advanced(x, y, size, "【字体缺失】", color)
except UnicodeEncodeError:
# 编码错误,显示替代字符
img.draw_string_advanced(x, y, size, "???", color)
技术亮点总结
多语言支持:完整的中英文和数字渲染能力
硬件加速:利用显示控制器的图形功能
内存优化:高效的字体缓存和位图管理
视觉设计:科学的颜色搭配和布局算法
系统稳定性:完善的异常处理和资源管理
实时性能:优化的渲染流水线,适合嵌入式环境
这个文字显示系统展示了CanMV K230在嵌入式GUI开发方面的强大能力,为复杂的用户界面应用奠定了坚实的技术基础。
实验场景图



返回首页
回到顶部

评论