【问题标题】:How to show a frame of a video file (image) with tkinter in python如何在python中使用tkinter显示视频文件(图像)的帧
【发布时间】:2016-08-04 12:23:20
【问题描述】:

我正在尝试使用 tkinter 显示视频帧(不是来自流)。下一步是允许用户在视频中向后或向前获取帧的按钮。我不得不说我在使用 python 编程方面是个新手。 所以首先我阅读了以下文章:

Python sn-ps:视频转图片http://srand.fr/blog/python%20import%20video.html

Tkinter PhotoImage 类:http://effbot.org/tkinterbook/photoimage.htm

问题是我不能用 imageio 或 VideoFileClip 转换的图像用 tkinter photoimage 显示它。我收到以下错误:

_tkinter.TclError: image "[[  …(some numbers)…   ]]" doesn't exist

这是我的简单代码。我希望你能帮助我:)

from moviepy.editor import VideoFileClip
from tkinter import *
import pylab

vid =VideoFileClip("example.mp4")

window = Tk()
window.title("Choose Frame")
window.geometry ("900x600")

count =20

photo = vid.get_frame(count)
label =Label(window, image = photo)
label.pack()

其他代码,同样的问题:

import imageio
from tkinter import *
import pylab

filename = './example.mp4'
vid = imageio.get_reader(filename,  'ffmpeg')

window = Tk()
window.title("Choose Frame")
window.geometry ("900x600")

count =20

photo = vid.get_data(count)
label =Label(window, image = photo)
label.pack()

【问题讨论】:

    标签: python video tkinter moviepy


    【解决方案1】:

    这有点晚了,但迟到总比没有好。

    这是我找到并稍作修改的一个工作示例,它适用于“.mp4”,视频但不适用于“.flv”,不知道为什么。

    注意:

    python 2.7 导入 Tkinter

    python 3 导入 tkinter

    import Tkinter as tk
    import threading
    import imageio
    from PIL import Image, ImageTk
    
    video_name = "test_video.mp4" #This is your video file path
    video = imageio.get_reader(video_name)
    
    def stream(label):
    
        frame = 0
        for image in video.iter_data():
            frame += 1                                    #counter to save new frame number
            image_frame = Image.fromarray(image)          
            image_frame.save('FRAMES/frame_%d.png' % frame)      #if you need the frame you can save each frame to hd
            frame_image = ImageTk.PhotoImage(image_frame)
            label.config(image=frame_image)
            label.image = frame_image
            if frame == 40: break                         #after 40 frames stop, or remove this line for the entire video
    
    if __name__ == "__main__":
    
        root = tk.Tk()
        my_label = tk.Label(root)
        my_label.pack()
        thread = threading.Thread(target=stream, args=(my_label,))
        thread.daemon = 1
        thread.start()
        root.mainloop()
    

    【讨论】:

      【解决方案2】:

      这是我尝试用 Tkinter 制作的播放器的另一个很好的工作示例,以及一些带有 Opencv 模块的示例代码。 这只是一个示例想法,绝不是完成代码。

      import cv2
      from Tkinter import *
      from PIL import Image, ImageTk
      import io
      import threading
      import os, sys
      
      def resize(image):
          im = image
          new_siz = siz
          im.thumbnail(new_siz, Image.ANTIALIAS)
          return im
      
      def size(event):
          global siz
          if siz == screenWH:
              siz = (200, 200)
          else:
              siz = screenWH
              win.state('zoomed')
          print 'size is: ', siz
      
      def view_frame_video():
          vc = cv2.VideoCapture('test_video.flv')
          if vc.isOpened():
              rval , frame = vc.read()
          else:
              rval = False
      
          while rval:
              rval, frame = vc.read()
              img =Image.fromarray(frame)
              img = resize(img)
              imgtk = ImageTk.PhotoImage(img)
              lbl.config(image=imgtk)
              lbl.img = imgtk
              if stop == True: 
                  vc.release()
                  break      #stop the loop thus stops updating the label and reading imagge frames
              cv2.waitKey(1)
          vc.release()
      
      def stop_():
          global stop
          stop = True
      
      def play():
          stop = False
          t = threading.Thread(target=view_frame_video)
          t.start()
      
      
      
      win = Tk()
      
      stop = None
      screenWH = (win.winfo_screenwidth(), win.winfo_screenheight())
      siz = (200, 200)
      
      Label(text='Press Play Button').pack()
      frm_ = Frame(bg='black')
      frm_.pack()
      lbl = Label(frm_, bg='black')
      lbl.pack(expand=True)
      lbl.bind('<Double-Button-1>', size)
      
      frm = Frame()
      frm.pack()
      Button(text='Play', command = play).pack(side=LEFT)
      Button(text='Stop', command = stop_).pack(side=LEFT)
      
      win.mainloop()
      

      【讨论】:

      • 你怎么能这样做,但在现有的画布中显示框架?
      猜你喜欢
      • 1970-01-01
      • 2021-09-12
      • 2018-11-28
      • 1970-01-01
      • 2023-03-09
      • 2013-09-28
      • 2021-04-28
      • 1970-01-01
      • 2012-09-01
      相关资源
      最近更新 更多