如何在Tkinter中将刚捕获的图片显示到指定Label组件中?
问题:点击Capture按钮后在captureLabel中显示最新捕获的图片
我正在开发一个项目,需要点击Capture按钮后,将刚捕获的图片显示到名为captureLabel的Label组件中,界面截图如下:

以下是我的完整main.py代码:
import tkinter as tk import tkinter.font as tkFont import cv2 from PIL import ImageTk, Image import os import time import uuid #setting title gui = tk.Tk(className='yolov5') #setting window size width=1024 height=768 screenwidth = gui.winfo_screenwidth() screenheight = gui.winfo_screenheight() alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) gui.geometry(alignstr) gui.resizable(width=False, height=False) cap = cv2.VideoCapture(0) IMAGES_PATH_CAPTURED = os.path.join('Captured') label = 'image' #functions def captureButton_command(): textLabel['text'] = "Capture button clicked.." ret, frame = cap.read() imgname = os.path.join(IMAGES_PATH_CAPTURED, label+'.'+str(uuid.uuid1())+'.jpg') cv2.imwrite(imgname, frame) time.sleep(1) print("Image saved to {}".format(IMAGES_PATH_CAPTURED)) def exitButton_command(): gui.destroy() def video_stream(): _, frame = cap.read() cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) img = Image.fromarray(cv2image) imgtk = ImageTk.PhotoImage(image=img) cameraLabel.imgtk = imgtk cameraLabel.configure(image=imgtk) cameraLabel.after(1, video_stream) #Capture Button captureButton=tk.Button(gui) captureButton["bg"] = "#efefef" ft = tkFont.Font(family='Times',size=15) captureButton["font"] = ft captureButton["fg"] = "#000000" captureButton["justify"] = "center" captureButton["text"] = "Capture" captureButton.place(x=10,y=220,width=150,height=50) captureButton["command"] = captureButton_command #Exit Button exitButton=tk.Button(gui) exitButton["bg"] = "#efefef" ft = tkFont.Font(family='Times',size=15) exitButton["font"] = ft exitButton["fg"] = "#000000" exitButton["justify"] = "center" exitButton["text"] = "Exit" exitButton.place(x=170,y=220,width=150,height=50) exitButton["command"] = exitButton_command #Message on top textLabel=tk.Label(gui) ft = tkFont.Font(family='Times',size=18) textLabel["font"] = ft textLabel["fg"] = "#333333" textLabel["justify"] = "left" textLabel["relief"] = "sunken" textLabel["text"] = "Press capture to capture image" textLabel.place(x=20,y=10,width=800,height=95) #Camera Feed Label cameraLabel=tk.Label(gui) cameraLabel["text"] = "Camera Feed" cameraLabel["borderwidth"] = "2px" cameraLabel["relief"] = "solid" cameraLabel.place(x=10,y=280,width=640,height=480) #Captured Images Label captureLabel = tk.Label(gui) captureLabel["borderwidth"] = "2px" captureLabel["relief"] = "solid" captureLabel.place(x=720,y=110,width=300,height=300) #Detected Images Label detectedLabel = tk.Label(gui) detectedLabel["borderwidth"] = "2px" detectedLabel["relief"] = "solid" detectedLabel.place(x=720,y=440,width=300,height=300) #end video_stream() gui.mainloop()
我曾尝试先将图片保存到文件夹再读取显示,但该方法仅能显示程序启动前已保存的图片,无法显示刚捕获的最新图片。我期望在指定的带边框Label中显示一张图片,且每次点击捕获按钮后能替换显示最新的捕获图片。
解决方法
修改captureButton_command函数,直接使用捕获到的帧转换格式后更新captureLabel,同时保留图片对象引用避免被回收,还要移除阻塞界面的time.sleep(1):
def captureButton_command(): textLabel['text'] = "Capture button clicked.." ret, frame = cap.read() # 保存图片(如果不需要保存可删除以下两行) imgname = os.path.join(IMAGES_PATH_CAPTURED, label+'.'+str(uuid.uuid1())+'.jpg') cv2.imwrite(imgname, frame) # 转换帧格式为Tkinter支持的RGBA cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) img = Image.fromarray(cv2image) # 调整图片尺寸适配captureLabel的300x300大小 img = img.resize((300, 300), Image.Resampling.LANCZOS) imgtk = ImageTk.PhotoImage(image=img) # 更新captureLabel并保留引用防止图片被回收 captureLabel.imgtk = imgtk captureLabel.configure(image=imgtk) print("Image saved to {}".format(IMAGES_PATH_CAPTURED))
这样修改后,每次点击Capture按钮,最新捕获的图片就会立刻显示在captureLabel中,并且每次点击都会替换为新图片。
内容的提问来源于stack exchange,提问作者Ariel Arevalo
相关产品推荐
相关产品推荐

