Skip to content

Commit 28defb0

Browse files
committed
* [maixcam2] optimize app chat
1 parent 996d0f0 commit 28defb0

File tree

4 files changed

+100
-3
lines changed

4 files changed

+100
-3
lines changed

projects/app_chat/app.png

2.87 KB
Loading

projects/app_chat/app.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ exclude:
1313
files:
1414
- assets/exit.jpg
1515
- assets/icon.png
16+
- app.png
1617
- app.yaml
1718
- main.py
1819
- README.md

projects/app_chat/assets/icon.png

1.64 KB
Loading

projects/app_chat/main.py

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,84 @@
33
from queue import Queue, Empty
44
import re
55

6+
from maix._maix.image import Image
7+
8+
class PagedText:
9+
def __init__(self, page_width = -1, page_height = -1):
10+
"""
11+
page_width: 每页宽度
12+
page_height: 每页最大行数
13+
char_width_func: 一个函数, 输入字符返回宽度 (例如 lambda c: 1 或字典映射)
14+
"""
15+
self.page_width = page_width
16+
self.page_height = page_height
17+
self.pages = [[]] # 每个元素是 page, page 是行的列表, 行是 (text, width)
18+
19+
def reset(self, page_width, page_height):
20+
self.page_width = page_width
21+
self.page_height = page_height
22+
self.pages = [[]]
23+
24+
def add_text(self, text):
25+
current_page = self.pages[-1]
26+
if not current_page:
27+
current_page.append(("", 0, 0)) # 初始化第一行
28+
29+
page_height_used = sum(line[2] for line in current_page)
30+
31+
for ch in text:
32+
line_text, _, line_h = current_page[-1]
33+
new_line_text = line_text + ch
34+
size = image.string_size(new_line_text)
35+
ch_w = size[0]
36+
ch_h = size[1]
37+
38+
# 尝试放到当前行
39+
if ch_w <= self.page_width:
40+
# 更新行
41+
new_w = ch_w
42+
new_h = max(line_h, ch_h)
43+
# 替换行
44+
current_page[-1] = (new_line_text, new_w, new_h)
45+
else:
46+
# 需要换行
47+
if page_height_used + line_h <= self.page_height:
48+
current_page.append((ch, ch_w, ch_h))
49+
page_height_used += line_h # 累加上一行高度
50+
else:
51+
# 需要换页
52+
self.pages.append([(ch, ch_w, ch_h)])
53+
current_page = self.pages[-1]
54+
page_height_used = ch_h
55+
56+
page_height_used = sum(line[2] for line in current_page)
57+
# print("OVER", line_text, line_w, line_h, page_height_used)
58+
59+
def clear(self):
60+
self.pages = [[]]
61+
62+
def print(self):
63+
for i, page in enumerate(self.pages):
64+
print(f"Page {i+1}:")
65+
page_height = sum(line[2] for line in page)
66+
for line_text, line_width, line_height in page:
67+
print(f" '{line_text}' (w={line_width}, h={line_height})")
68+
print(f" -> total height used = {page_height}")
69+
print()
70+
71+
def draw_last_page_on(self, img:image.Image, color: image.Color = image.COLOR_WHITE):
72+
if img.width() != self.page_width or img.height() != self.page_height:
73+
return
74+
75+
current_page = self.pages[-1]
76+
if not current_page:
77+
return
78+
79+
height = 0
80+
for line_text, _, line_height in current_page:
81+
img.draw_string(0, height, line_text, color, wrap_space=0)
82+
height += line_height
83+
684
class App:
785
def __init__(self):
886
image.load_font("sourcehansans", "/maixapp/share/font/SourceHanSansCN-Regular.otf", size = 20)
@@ -74,15 +152,18 @@ def __init__(self):
74152
self.tts_thread = threading.Thread(target=self.tts_thread_handle, daemon=True)
75153
self.tts_thread.start()
76154

155+
self.page_text = PagedText()
156+
77157
def player_thread_handle(self):
158+
bytes_per_frame = 2
78159
while not app.need_exit():
79160
try:
80161
pcm = self.player_queue.get(timeout=500)
81162
t = time.ticks_ms()
82163
print('self.player.remaining size1', self.player.get_remaining_frames())
83164
while not app.need_exit():
84165
idle_frames = self.player.get_remaining_frames()
85-
write_frames = len(pcm) / self.player.frame_size()
166+
write_frames = len(pcm) / bytes_per_frame
86167
print('idle', idle_frames, 'write', write_frames)
87168
if idle_frames >= write_frames:
88169
break
@@ -110,10 +191,22 @@ def tts_thread_handle(self):
110191

111192
def __llm_on_reply(self, obj, resp):
112193
print(resp.msg_new, end="")
194+
ts_data = self.ts.read()
113195
img = image.Image(320, 240, bg=image.COLOR_BLACK)
114196
self.__draw_string_upper_center(img, text="Run LLM..", color=image.COLOR_GREEN)
115197
# img.draw_string(0, 0, "Run LLM..", image.COLOR_GREEN)
116-
img.draw_string(0, 30, resp.msg, image.COLOR_WHITE)
198+
199+
self.page_text.add_text(resp.msg_new)
200+
new_img = image.Image(320, 210, bg=image.COLOR_BLACK)
201+
self.page_text.draw_last_page_on(new_img, image.COLOR_WHITE)
202+
img.draw_image(0, 30, new_img)
203+
204+
exit_img_x = 0
205+
exit_img_y = 0
206+
img.draw_image(exit_img_x, exit_img_y, self.exit_img)
207+
if ts_data[2] and 0<=ts_data[0]<=self.exit_img.width() + exit_img_x*2 and 0 <=ts_data[1]<=self.exit_img.height() + exit_img_y*2:
208+
print('exit')
209+
app.set_exit_flag(True)
117210
self.disp.show(img)
118211

119212
self.llm_last_msg += resp.msg_new
@@ -207,7 +300,9 @@ class Status:
207300
if asr_result:
208301
img.draw_string(0, 30, asr_result, image.COLOR_WHITE)
209302
elif llm_result:
210-
img.draw_string(0, 30, llm_result, image.COLOR_WHITE)
303+
new_img = image.Image(320, 210, bg=image.COLOR_BLACK)
304+
self.page_text.draw_last_page_on(new_img, image.COLOR_WHITE)
305+
img.draw_image(0, 30, new_img)
211306

212307
exit_img_x = 0
213308
exit_img_y = 0
@@ -247,6 +342,7 @@ class Status:
247342
status = Status.LLM
248343
elif status == Status.LLM:
249344
if asr_result:
345+
self.page_text.reset(320, 210)
250346
llm_result0 = self.llm.send(asr_result)
251347
llm_result = llm_result0.msg
252348
self.llm.clear_context()

0 commit comments

Comments
 (0)