2016-08-04 783 views
0

我試圖用tkinter顯示視頻幀(不是來自流)。下一步是允許用戶在視頻中向後或向前獲取幀的按鈕。我不得不說,我是用python進行編程的新手段。 所以首先我仔細閱讀以下條款:如何使用tkinter在Python中顯示視頻文件(圖像)的幀

的Python代碼片段:視頻轉換爲圖像http://srand.fr/blog/python%20import%20video.html

的Tkinter的光象類: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() 

回答

1

這是一個有點晚,但遲到總比不到好。

這裏是一個工作例子,我發現並修改了一下,這一點也適用「約會專家' ,影片,但不是以」 FLV的」,不知道爲什麼。

注:

蟒蛇2.7進口的Tkinter

巨蟒-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() 
0

這裏是一個球員,我試圖讓與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() 
相關問題