diff --git a/app.py b/app.py index 68a8a9d5b4e41904530a2003be30c5e4349092f3..2b14e5a5cc581601e9422c6213b91a2af28cde58 100644 --- a/app.py +++ b/app.py @@ -24,24 +24,24 @@ class DocScannerApp: # 在窗口中创建一个宽600,高400画布 # 用于把图片和裁剪框绘制上去 - self.canvas = #TODO + self.canvas = tk.Canvas(self.root, width=600, height=400) # 将画布添加到窗口中 - #TODO + self.canvas.pack() # 为画布绑定鼠标事件 # 鼠标左键按下,释放和移动事件都绑定到方法:mouse_callback 上 # 注意绑定的事是实例方法,不要忘了self - #TODO # 鼠标按下事件 - #TODO # 鼠标释放事件 - #TODO # 鼠标移动事件 + self.canvas.bind("", self.mouse_callback) # 鼠标按下事件 + self.canvas.bind("", self.mouse_callback) # 鼠标释放事件 + self.canvas.bind("", self.mouse_callback) # 鼠标移动事件 # 创建一个 "Select Image" 按钮,点击时执行 self.select_image 函数 btn_select = tk.Button(self.root, text="Select Image", command=self.select_image) btn_select.pack(side=tk.LEFT) # 将按钮添加到窗口左侧 - self.show_mouse_move = #TODO # 创建一个 BooleanVar 实例来保存复选框的状态 + self.show_mouse_move = tk.BooleanVar() # 创建一个 BooleanVar 实例来保存复选框的状态 # 创建一个复选框,文本为 "Show Mouse Move",把状态与 self.show_mouse_move 绑定 - chk_show_mouse_move = #TODO + chk_show_mouse_move = tk.Checkbutton(self.root, text="Show Mouse Move", variable=self.show_mouse_move) chk_show_mouse_move.pack(side=tk.LEFT) # 将复选框添加到窗口左侧 # 创建一个 "Crop" 按钮,点击时执行 self.crop 函数 @@ -54,11 +54,10 @@ class DocScannerApp: self.img, self.corners = self.doc_scanner.load_image(file_path) # 加载图片和角落 img_height, img_width, _ = self.img.shape # 获取图片的高度和宽度 if img_height > 600 or img_width > 800: # 如果图片的高度大于600或宽度大于800 - - scale = #TODO # 计算缩放比例 - self.img = #TODO # 缩放图片 - self.corners = #TODO # 缩放角落 - img_height, img_width, _ = self.img.shape # 更新图片的高度和宽度 + scale = min(600 / img_height, 800 / img_width) # 计算缩放比例 + self.img = cv.resize(self.img, (int(img_width * scale), int(img_height * scale))) # 缩放图片 + self.corners = self.corners * scale # 缩放角落 + img_height, img_width, _ = self.img.shape # 更新图片的高度和宽度 self.canvas.config(width=img_width, height=img_height) # 调整画布的大小以适应图片 self.canvas.pack() # 更新画布 @@ -71,7 +70,7 @@ class DocScannerApp: if event.type == tk.EventType.ButtonPress: # 如果是鼠标按下事件 print(f"鼠标在({x},{y})按下") for idx, corner in enumerate(self.corners): # 遍历每个角落点 - #TODO: # 如果鼠标位置和角落的距离小于10 + if np.linalg.norm(corner - np.array([x, y])) < 10: # 如果鼠标位置和角落的距离小于10 self.dragging_idx = idx # 设置正在拖动的角落索引值为当前的角落的索引值 print(f"要开始拖动角落: corners[{idx}]={corner} , 所以变量: dragging_idx 别设置为 {idx}") break # 已经找到了要拖动的点,所以跳出循环 @@ -79,7 +78,7 @@ class DocScannerApp: print(f"鼠标在({x},{y})释放") self.dragging_idx = -1 elif event.type == tk.EventType.Motion: # 如果是鼠标移动事件 - if(self.show_mouse_move.get()): + if self.show_mouse_move.get(): print(f"鼠标在({x},{y})移动") if self.dragging_idx != -1: # 如果正在拖动一个角落 self.corners[self.dragging_idx] = np.array([x, y]) # 更新该角落的位置 @@ -92,7 +91,7 @@ class DocScannerApp: # 在图片上绘制一个绿色的圆形标记角落的位置 cv.circle(img_copy, tuple(corner.astype(int)), 5, (0, 255, 0), -1) # 在图片上绘制一个绿色的,宽度为2的多边形连接所有角落 - #TODO + cv.polylines(img_copy, [self.corners.astype(int)], isClosed=True, color=(0, 255, 0), thickness=2) img_tk = self.cv2image_to_tkinter_image(img_copy) # 将 OpenCV 图片转换为 Tkinter 图片 self.canvas.create_image(0, 0, anchor=tk.NW, image=img_tk) # 在画布上创建图片 self.canvas.image = img_tk # 保存图片,防止被垃圾回收 @@ -103,7 +102,6 @@ class DocScannerApp: pil_image = Image.fromarray(cv2_image_rgb) # 将数组转换为 PIL 图片 return ImageTk.PhotoImage(pil_image) # 将 PIL 图片转换为 Tkinter 图片 - def crop(self): """裁剪图片。""" cropped_img = self.doc_scanner.crop_image(self.img, self.corners) # 调用 DocScanner 的 crop_image 方法来裁剪图片 @@ -122,4 +120,4 @@ class DocScannerApp: if __name__ == "__main__": app = DocScannerApp() # 创建 DocScannerApp 类的实例 - app.run() # 运行应用程序 + app.run() # 运行应用程序 \ No newline at end of file