Python 如何使用cv2.videowriter使用Tkinter录制计算机屏幕,而不在录制时显示屏幕(imgshow)

Python 如何使用cv2.videowriter使用Tkinter录制计算机屏幕,而不在录制时显示屏幕(imgshow),python,python-3.x,video,tkinter,cv2,Python,Python 3.x,Video,Tkinter,Cv2,实际上,我想做的是: 要使用Tkinter按钮执行以下操作: 1.1。开始录制屏幕 1.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 St

实际上,我想做的是:

  • 要使用Tkinter按钮执行以下操作:

    1.1。开始录制屏幕

    1.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) 。当用户单击“开始”按钮时开始录制

    (b) 。在“帧”窗口中录制时同时显示屏幕

    (c) 。当用户按下电脑上的“esc”键时停止录制

    (d) 。将最终视频(名为“rec.avi”)保存在路径
    C:\IQOutput\

    但我希望该计划有以下几种选择:

    (a) 。当用户单击“开始”按钮时,它开始记录屏幕(已在工作)

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

    (c) 。当用户单击Bstops按钮时,它停止记录屏幕

    (d) 。它将名为“rec.avi”的最终视频保存在路径
    c:\IQOutput\

    我回答了我提出的问题(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)一旦我单击“开始”按钮,此按钮功能将继续对捕获图像帧进行视频处理(2)因此在按下“esc”之前,我无法使用“屏幕视频”窗口中的其他按钮停止b开始按钮功能的键。

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

    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
    

    我找到了另一种方法,我使用python调用oCam(一个非常好的屏幕截图和屏幕录制应用程序,可以获得高质量的图片和mp4视频),并使用tkinter在oCam中按下“开始/停止屏幕录制”的热键,现在它工作得很好。现在我不需要使用cv2。