From b0ff800826e55622a6d00bda6e5b951d887992fb Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 29 Oct 2025 16:53:34 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E9=9B=86=E5=8D=A1bug=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preview.py | 99 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/preview.py b/preview.py index 58cf376..6d149a9 100644 --- a/preview.py +++ b/preview.py @@ -198,11 +198,26 @@ class PreviewWindow: return # 计算每个预览窗口的位置和大小 - window_width = root.winfo_width() if root.winfo_width() > 1 else 1000 - window_height = root.winfo_height() if root.winfo_height() > 1 else 700 - - cell_width = window_width // columns - cell_height = window_height // rows + # 确保画布已完全初始化 + root.update_idletasks() + canvas.update_idletasks() + + # 获取画布实际尺寸 + canvas_width = canvas.winfo_width() + canvas_height = canvas.winfo_height() + + # 如果画布还没初始化,使用默认值 + if canvas_width <= 1 or canvas_height <= 1: + canvas_width = 1000 + canvas_height = 700 + + # 确保尺寸有效 + if canvas_width < 100 or canvas_height < 100: + canvas_width = 1000 + canvas_height = 700 + + cell_width = max(10, canvas_width // columns) + cell_height = max(10, canvas_height // rows) # 先收集所有需要显示的图像 images_to_draw = [] @@ -218,31 +233,57 @@ class PreviewWindow: center_y = y + cell_height // 2 name = self.caps[idx]['name'] - if idx in self.frames and self.frames[idx] is not None: + # 检查帧数据 + has_frame = idx in self.frames and self.frames[idx] is not None + + if has_frame: # 调整图像大小 try: frame = self.frames[idx] h, w = frame.shape[:2] - scale = min(cell_width / w, cell_height / h) * 0.9 - new_w = int(w * scale) - new_h = int(h * scale) + + # 确保尺寸有效 + if w <= 0 or h <= 0: + texts_to_draw.append((center_x, center_y, f"{name}\n尺寸无效", 'red')) + frame_idx += 1 + continue + + # 计算缩放比例,留一些边距 + scale = min(cell_width / w, cell_height / h, 1.0) * 0.85 + new_w = max(1, int(w * scale)) + new_h = max(1, int(h * scale)) + + # 确保缩放后的尺寸有效 + if new_w <= 0 or new_h <= 0: + texts_to_draw.append((center_x, center_y, f"{name}\n缩放失败", 'red')) + frame_idx += 1 + continue + + # 调试输出(仅前几次) + if frame_idx == 0 and len(images_to_draw) == 0: + print(f"🔍 预览调试: 画布={canvas_width}x{canvas_height}, 单元格={cell_width}x{cell_height}, 原始帧={w}x{h}, 缩放后={new_w}x{new_h}") resized_frame = cv2.resize(frame, (new_w, new_h)) # 转换为PIL图像 + # 确保颜色通道正确(BGR -> RGB) + if len(resized_frame.shape) == 3 and resized_frame.shape[2] == 3: + resized_frame = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2RGB) pil_image = Image.fromarray(resized_frame) photo = ImageTk.PhotoImage(image=pil_image) # 保持引用,避免被GC self.photo_objects[idx] = photo images_to_draw.append((photo, center_x, center_y)) - texts_to_draw.append((center_x, y + 20, name, 'white')) + texts_to_draw.append((center_x, y + 15, name, 'white')) frame_idx += 1 except Exception as e: # 忽略pyimage相关错误,避免刷屏 if "pyimage" not in str(e).lower(): print(f"处理帧 {idx} 错误: {e}") + import traceback + traceback.print_exc() # 如果处理失败,显示等待提示 texts_to_draw.append((center_x, center_y, f"{name}\n处理失败", 'red')) frame_idx += 1 @@ -254,15 +295,27 @@ class PreviewWindow: # 清空画布 canvas.delete("all") - # 绘制所有图像和文本 + # 先绘制所有图像(底层) + if images_to_draw: + if frame_idx == len(images_to_draw): + print(f"✅ 准备绘制 {len(images_to_draw)} 个图像") + for photo, x, y in images_to_draw: - canvas.create_image(x, y, image=photo, anchor='center') + try: + canvas.create_image(x, y, image=photo, anchor='center') + except Exception as e: + if "pyimage" not in str(e).lower(): + print(f"绘制图像错误: {e}") + # 再绘制所有文本(上层) for x, y, text, color in texts_to_draw: - if color == 'white': - canvas.create_text(x, y, text=text, fill=color, font=('Arial', 12, 'bold')) - else: - canvas.create_text(x, y, text=text, fill=color, font=('Arial', 12)) + try: + if color == 'white': + canvas.create_text(x, y, text=text, fill=color, font=('Arial', 10, 'bold')) + else: + canvas.create_text(x, y, text=text, fill=color, font=('Arial', 10)) + except Exception as e: + print(f"绘制文本错误: {e}") except Exception as e: print(f"更新帧错误: {e}") @@ -289,8 +342,15 @@ class PreviewWindow: canvas.bind('', on_canvas_click) - # 使用after在主线程中循环刷新 - root.after(33, update_frames_once) + # 等待窗口完全初始化后再开始更新 + def start_updates(): + """延迟启动更新,确保窗口已完全显示""" + root.update_idletasks() + root.update() + update_frames_once() + + # 使用after在主线程中循环刷新(延迟启动) + root.after(100, start_updates) def on_closing(): """关闭窗口""" @@ -335,6 +395,9 @@ class PreviewWindow: new_h = int(h * scale) resized_frame = cv2.resize(frame, (new_w, new_h)) + # 确保颜色通道正确(BGR -> RGB) + if len(resized_frame.shape) == 3 and resized_frame.shape[2] == 3: + resized_frame = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2RGB) pil_image = Image.fromarray(resized_frame) photo = ImageTk.PhotoImage(image=pil_image) # 保存引用到字典,确保不被GC