自动化录制及手动截图

import os
import time                                                     
import json                                                    
import pynput
import ctypes
import threading
import tkinter as tk                                                    
from time import sleep
import tkinter.filedialog
from PIL import Image, ImageGrab,ImageTk


command_list = []                                                   # 用来存储用户的操作
global isRunning
isRunning = True                                                    # 是否在运行,用于实现在按esc后退出的功能
startTime = 0                                                       # 开始时间,会在之后进行初始化


def get_image(file_nam, width, height):                             # 读取背景图
    im = Image.open(file_nam).resize((width, height))
    return ImageTk.PhotoImage(im)


def on_key_press(key):                                              # 当按键按下时记录
    if key == pynput.keyboard.Key.esc:                              # 如果是esc
        win.state('normal')
        isRunning = False                                           # 通知监听鼠标的线程
        mouse = pynput.mouse.Controller()                           # 获取鼠标的控制器
        mouse.click(pynput.mouse.Button.left)                       # 通过模拟点击鼠标以执行鼠标的线程,然后退出监听.
        return False                                                # 监听函数return False表示退出监听
    command_list.append(("press", (str(key).strip("'")), time.time()-startTime))

   
def on_key_release(key):                                            # 但按键松开时记录
    command_list.append(("release", (str(key).strip("'")),time.time()-startTime))

    
def on_mouse_click(x, y, button, pressed):
    if not isRunning:                                               # 如果已经不在运行了
        return False                                                # 退出监听
    if not pressed:                                                 # 如果是松开事件
        return True                                                 # 不记录
    command_list.append(("click", (x, y, str(button)), time.time() - startTime))


def start_key_listen():                                             # 用于开始按键的监听
    with pynput.keyboard.Listener(on_press = on_key_press, on_release = on_key_release) as listener:
        listener.join()


def start_mouse_listen():                                           # 用于开始鼠标的监听
    with pynput.mouse.Listener(on_click = on_mouse_click) as listener:
        listener.join()       


def toFile(command_list, path):                                     # 保存为文件,参数分别为操作记录和保存位置
    with open(path, "w") as f:
        f.write(json.dumps(command_list))                           # 使用json格式写入
    f.close()


class FreeCapture():
    def __init__(self, win, img):
        self.X = tkinter.IntVar(value = 0)                          # 变量X和Y用来记录鼠标左键按下的位置
        self.Y = tkinter.IntVar(value = 0)
        screenWidth = win.winfo_screenwidth()                       # 屏幕尺寸
        screenHeight = win.winfo_screenheight()
        self.top = tkinter.Toplevel(win, width = screenWidth, height = screenHeight)# 创建顶级组件容器
        self.top.overrideredirect(True)                             # 不显示最大化、最小化按钮
        self.canvas = tkinter.Canvas(self.top, bg = 'white', width = screenWidth, height = screenHeight)
        self.image = tkinter.PhotoImage(file = img)                 # 显示全屏截图,在全屏截图上进行区域截图
        self.canvas.create_image(screenWidth // 2, screenHeight // 2, image = self.image)
        self.lastDraw = None

        
        def onLeftButtonDown(event):                                # 鼠标左键按下的位置
            self.X.set(event.x)
            self.Y.set(event.y)
            self.sel = True                                         # 开始截图


        self.canvas.bind('<Button-1>', onLeftButtonDown)


        def onLeftButtonMove(event):
            if not self.sel:                                        # 鼠标左键移动,显示选取的区域
                return
            try:                                                    # 删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形
                self.canvas.delete(self.lastDraw)
            except Exception as e:
                pass
            self.lastDraw = self.canvas.create_rectangle(self.X.get(), self.Y.get(), event.x, event.y, outline = 'red')

 
        def onLeftButtonUp(event):                                  # 获取鼠标左键抬起的位置,保存区域截图
            self.sel = False
            try:
                self.canvas.delete(self.lastDraw)
            except Exception as e:
                pass
            time.sleep(0.5)
            left, right = sorted([self.X.get(), event.x])           # 考虑鼠标左键从右下方按下而从左上方抬起的截图
            top, bottom = sorted([self.Y.get(), event.y])
            pic = ImageGrab.grab((left + 1, top + 1, right, bottom))
            x = left+1, top+1, right, bottom
            bbox = (x)
            im = ImageGrab.grab(bbox)
            im.save('../录制截图.png')                              # 参数 保存截图文件的路径
            self.top.destroy()                                      # 关闭当前窗口
            with open('../坐标.txt', "w") as z:
                z.write(str(x))
            z.close()
        self.canvas.bind('<B1-Motion>', onLeftButtonMove)           # 按下左键
        self.canvas.bind('<ButtonRelease-1>', onLeftButtonUp)       # 抬起左键
        self.canvas.pack(fill = tkinter.BOTH, expand = tkinter.YES) # 让canvas充满窗口,并随窗口自动适应大小

        
def screenShot():
    win.state('icon')                                               # 最小化主窗体
    time.sleep(0.2)
    im = ImageGrab.grab()
    im.save('temp.png')                                             # 暂存全屏截图
    im.close()
    w = FreeCapture(win, 'temp.png')                                # 进行自由截屏
    threebutton.wait_window(w.top)
    win.state('normal')                                             # 截图结束,恢复主窗口,并删除temp.png文件
    win.wm_attributes('-topmost',1)                                 # 置顶页面
    os.remove('temp.png')


def Start():                                                        # 录制
    win.state('icon')                                               # 最小化主窗体
    global startTime
    startTime = time.time()                                         # 初始化开始时间
    key_listen_thread = threading.Thread(target = start_key_listen) # 创建用于监听按键的线程
    mouse_listen_thread = threading.Thread(target = start_mouse_listen) # 创建用于监听鼠标的线程
    key_listen_thread.start()                                       # 运行线程
    mouse_listen_thread.start()
    key_listen_thread.join()                                        # 等待线程结束,也就是等待用户按下esc
    mouse_listen_thread.join()
    toFile(command_list,'../录制记录.json')                         # 保存文件


def Finish():                                                       # 终结程序
    os._exit(0)


def thread_it(func, *args):
    t = threading.Thread(target = func, args = args)                # 创建
    t.setDaemon(True)                                               # 守护
    t.start()                                                       # 启动


win = tk.Tk()
win.wm_attributes('-topmost', 1)                                    # 置顶页面
win.title('应用执行框')                                             # 设置窗口title和大小
win.geometry('200x200')
win.resizable(0, 0)                                                 # 防止用户调整尺寸
canvas = tk.Canvas(win, height = 500, width = 500)                  # 画布  设置背景图片
im_win = get_image('../录制背景图.png', width = 680, height = 650)
canvas.create_image(250, 250, image = im_win)
canvas.pack()
onebutton = tk.Button(win, bg = 'Light blue', text = "录制", width = 5, height = 2, command = lambda :thread_it(main))
twobutton = tk.Button(win, bg = 'Light blue', text = "关闭", width = 5, height =2 , command = lambda :thread_it(Finish))
threebutton = tk.Button(win, bg = 'Light blue', text = "截屏", width = 5, height = 2, command = lambda :thread_it(screenShot))
onebutton.place(x = 5, y = 150)
twobutton.place(x = 150, y = 150)
threebutton.place(x = 75, y =150)
win.mainloop()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值