如何在 tkinter (Python3.x) 中单击鼠标逐帧显示?
How to go frame by frame on mouse click in tkinter (Python3.x)?
我有来自几个来源的关于堆栈溢出的代码,这些代码是我放在一起的。它播放视频并记录 window 中的点击位置。我希望它逐帧播放并在每次单击后前进。我不确定如何开始。
video_name = input_file()
video = imageio.get_reader(video_name)
def stream(label):
for image in video.iter_data():
image_frame = Image.fromarray(image)
frame_image = ImageTk.PhotoImage(image_frame)
label.config(image=frame_image)
label.image = frame_image
if __name__ == "__main__":
def leftClick(event):
x = root.winfo_pointerx() - root.winfo_rootx()
y = root.winfo_pointery()- root.winfo_rooty()
print(x, y)
root = tk.Tk()
my_label = tk.Label(root)
my_label.bind("<Button-1>", leftClick)
my_label.bind("<Button-3>", rightClick)
my_label.pack()
thread = threading.Thread(target=stream, args=(my_label,))
thread.daemon = 1
thread.start()
root.mainloop()
感谢您对我的任何建议。
您应该使用 video.get_data(...)
加载帧而不是使用 for
循环。您也不需要使用 thread
从视频中读取帧,使用点击事件处理程序。以下是您的代码的修改版本作为示例:
frame_index = 0 # current displayed frame index in the video file
def stream(label, offset=0):
global frame_index
try:
# read a frame image from video file
image = video.get_data(frame_index+offset)
# convert the image to tkinter supported format
image_frame = Image.fromarray(image)
frame_image = ImageTk.PhotoImage(image_frame)
label.config(image=frame_image)
label.image = frame_image
# update frame_index if image is loaded successfully
frame_index += offset
except Exception as ex:
print('Error loading frame:', ex)
if __name__ == "__main__":
video_name = input_file()
video = imageio.get_reader(video_name)
root = tk.Tk()
my_label = tk.Label(root)
my_label.bind("<Button-1>", lambda e: stream(my_label, +1))
my_label.bind("<Button-3>", lambda e: stream(my_label, -1))
my_label.pack()
stream(my_label) # load first frame
root.mainloop()
video.close() # close the reader
注意鼠标左键点击用于显示视频中的下一张图片,鼠标右键点击用于显示视频中的上一张图片文件。
我有来自几个来源的关于堆栈溢出的代码,这些代码是我放在一起的。它播放视频并记录 window 中的点击位置。我希望它逐帧播放并在每次单击后前进。我不确定如何开始。
video_name = input_file()
video = imageio.get_reader(video_name)
def stream(label):
for image in video.iter_data():
image_frame = Image.fromarray(image)
frame_image = ImageTk.PhotoImage(image_frame)
label.config(image=frame_image)
label.image = frame_image
if __name__ == "__main__":
def leftClick(event):
x = root.winfo_pointerx() - root.winfo_rootx()
y = root.winfo_pointery()- root.winfo_rooty()
print(x, y)
root = tk.Tk()
my_label = tk.Label(root)
my_label.bind("<Button-1>", leftClick)
my_label.bind("<Button-3>", rightClick)
my_label.pack()
thread = threading.Thread(target=stream, args=(my_label,))
thread.daemon = 1
thread.start()
root.mainloop()
感谢您对我的任何建议。
您应该使用 video.get_data(...)
加载帧而不是使用 for
循环。您也不需要使用 thread
从视频中读取帧,使用点击事件处理程序。以下是您的代码的修改版本作为示例:
frame_index = 0 # current displayed frame index in the video file
def stream(label, offset=0):
global frame_index
try:
# read a frame image from video file
image = video.get_data(frame_index+offset)
# convert the image to tkinter supported format
image_frame = Image.fromarray(image)
frame_image = ImageTk.PhotoImage(image_frame)
label.config(image=frame_image)
label.image = frame_image
# update frame_index if image is loaded successfully
frame_index += offset
except Exception as ex:
print('Error loading frame:', ex)
if __name__ == "__main__":
video_name = input_file()
video = imageio.get_reader(video_name)
root = tk.Tk()
my_label = tk.Label(root)
my_label.bind("<Button-1>", lambda e: stream(my_label, +1))
my_label.bind("<Button-3>", lambda e: stream(my_label, -1))
my_label.pack()
stream(my_label) # load first frame
root.mainloop()
video.close() # close the reader
注意鼠标左键点击用于显示视频中的下一张图片,鼠标右键点击用于显示视频中的上一张图片文件。