如何使用cv2.videowriter在不显示的情况下使用tkinter录制屏幕视频(imgshow)

时间:2018-06-27 03:26:05

标签: python python-3.x video tkinter cv2

现在我要做的是:

  1. 使用tkinter的按钮

    1.1开始录制屏幕视频

    1.2。停止录制屏幕视频

  2. 但在录制过程中不会同时显示视频。

下面是代码:

import tkinter as tk
import cv2
import numpy as np
from PIL import ImageGrab

window = tk.Tk()
window.title('ScreenVideo')
window.geometry('350x300')

#ScreenVideo

def StartS():
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    vid=cv2.VideoWriter("c:\\IQOutput\\rec.avi", fourcc, 10, (990,690))

    while(True):
        img = ImageGrab.grab(bbox=(10,10,1000,700))
        img_np=np.array(img)
        frame=cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
        vid.write(frame)
        cv2.imshow("frame", frame)
        key=cv2.waitKey(1)
        if key==27:
            break

    vid.release()
    cv2.destroyAllWindows()

bstarts = tk.Button(window, text='StartRe', font=('Arial', 8), bg='light pink', width=5, height=1, command=StartS)     
bstarts.place(x=280, y=80, anchor='nw')

bstops = tk.Button(window, text='StopRe', font=('Arial', 8), bg='light pink', width=5, height=1, command=StopRe)     
bstops.place(x=280, y=120, anchor='nw')

到目前为止,以上代码只能

(a)。单击bstarts按钮开始录制屏幕视频

(b)。在“框架”窗口中同时显示屏幕视频

(c)。停止录制的方法是在PC中按“ esc”。

(d)。文件夹c:\ IQOutput \

中的屏幕视频剪辑“ rec.avi”

但是我想要的是:

(a)。单击bstarts按钮开始录制屏幕视频(在以上代码中有效)

(b)。不能在屏幕上同时显示屏幕视频(在录制过程中如何删除或隐藏与“ imshow”相关的功能?)

(c)。单击bstops按钮停止录制屏幕视频

(d)。 c:\IQOutput\文件夹中的屏幕视频剪辑“ rec.avi”

2 个答案:

答案 0 :(得分:0)

我回答了(b)我问的问题:“(b)。不要在屏幕上同时显示屏幕视频(在录制过程中如何删除或隐藏与“ imshow”相关的功能?)”。我的学习是视频作家必须与imshow合作。所以我的解决方法是调整大小并移动imshow窗口,代码如下:

    ....
    vid.write(frame)
    cv2.resizeWindow('frame', 20,20)
    cv2.moveWindow("frame", 5,5) 
    cv2.imshow("frame", frame) 
    ......

现在imshow窗口很小,并且位于左上角,不会干扰我要记录的内容。

但是我仍然不知道如何使用tkiinter的按钮来停止记录。原因是(1)单击bstarts按钮后,此按钮功能将继续在捕获图像帧上播放为视频(2),因此在按“ esc”键停止bstarts按钮之前,无法在“ screenvideo”窗口中使用其他按钮功能。

答案 1 :(得分:0)

您可以使用递归而不是while循环,因为在tkinter中使用while循环时,它们永远不会释放按钮,因此您不可能停止循环。 但是,当您使用递归时,很容易通过调用其他功能(如停止按钮)来停止循环,并且可以将after_id递归更改为“无”。

def ScreenRe():
    global after_id
    global secs

    secs += 1
    if secs % 1 == 0:  # every other second
        img = pyautogui.screenshot()
        frame=np.array(img)
        frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
        out.write(frame)
        cv2.imshow('show',frame)
    after_id = top.after(1000, ScreenRe)  # check again in 1 second

def start():
    global secs
    secs = 0
    ScreenRe()  # start repeated checking

def stop():
    global after_id
    if after_id:
        top.after_cancel(after_id)
        after_id = None