分享免费的编程资源和教程

网站首页 > 技术教程 正文

基于Python的截图工具实现

goqiw 2024-09-04 18:55:16 技术教程 23 ℃ 0 评论

导读


本文主要介绍使用python、pynput库和pyscreeze库实现截图功能。


项目介绍


本文将创建一个程序用于屏幕截图。对于该程序需要如下几个包:pynput、pyscreeze、os、datetime,其中前两个库需要单独安装。其中pynput用于监听鼠标键盘事件,自动化操作;pyscreeze库用于截图、对比图片、定位元素;os用于与操作系统交互,可以进行文件、文件夹操作;datetime用于获取日期时间。这是对项目和库的简短介绍,下面将详细介绍准备工作和实现步骤。


准备工作


安装相关库

#安装pynput

pip install pynput

#安装 pyscreeze

pip install pyscreeze


以下第三方库用于改进程序,是否安装取决于个人

#安装pyautogui

pip install pyautogui

#安装tkinter

pip install tkinter

#安装pyautogui

pip install pyautogui


实现步骤

01

导入所需要的所有库

from pynput import mouse
import pyscreeze
import os
import datetime


02

设计鼠标点击事件,当鼠标点击时获取所点击的坐标

start_and_end=[] # 坐标列表
def on_click(x, y, button, pressed):
    global start_and_end
    if pressed == True:  # 当鼠标被按下时才会选取
        start_and_end.append((x, y))  # 将选取坐标添加到列表

03

判断已选取坐标数量,数量为2时停止获取坐标

def on_click(x, y, button, pressed):
    global start_and_end
    if pressed == True:  # 当鼠标被按下时才会选取
        start_and_end.append((x, y))  #将选取坐标添加到列表
        # 判断已选取几个点
        if len(start_and_end) == 1:
            print("已选取第一个点:",x,y)
        elif len(start_and_end) == 2:
            print("已选取第二个点:",x,y)
            return False

04

判断保存截图的目标文件夹是否存在

path = "screen"  # 相对路径
if path not in os.listdir():  # 判断相对路径文件夹是否存在
    os.mkdir(path) # 创建文件夹

05

以当前时间设置为截图默认名称

nowDatatime = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%d-%H%M%S")  # 获取当前时间

06

实现截图功能

"""
截图功能
因为pyscreeze不能为负数,所以选取点只能从左上到右下
"""
pyscreeze.screenshot("./screen/{}.png".format(nowDatatime),
                              region=(start_and_end[0][0],
                              start_and_end[0][1],
                              start_and_end[1][0]-start_and_end[0][0],
                              start_and_end[1][1]-start_and_end[0][1],
                              )

07

进行鼠标监听

listenerMouse = mouse.Listener(on_click=on_click)  # 监听鼠标
listenerMouse.start()  # 开始
listenerMouse.join()  # 添加监听器
listenerMouse.stop()  # 结束

08

完整代码如下

from pynput import mouse
import pyscreeze
import os
import datetime
start_and_end=[]

# 鼠标click监听
def on_click(x, y, button, pressed):
    global start_and_end
    if pressed == True:  # 当鼠标被按下时才会选取
        start_and_end.append((x, y))  #将选取坐标添加到列表
        # 判断以选取几个点
        if len(start_and_end) == 1:
            print("已选取第一个点:",x,y)
        elif len(start_and_end) == 2:
            print("以选取第二个点:",x,y)
            path = "screen"  # 相对路径
            if path not in os.listdir():  # 判断相对路径文件夹是否存在
                os.mkdir(path)
            # 获取当前时间
            nowDatatime = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%d-%H%M%S")      
            """
            截图
            因为pyscreeze不能为负数,所以选取点只能从左上到右下
            """
            pyscreeze.screenshot("./screen/{}.png".format(nowDatatime),
                                        region=(start_and_end[0][0],
                                        start_and_end[0][1],
                                        start_and_end[1][0]-start_and_end[0][0],
                                        start_and_end[1][1]-start_and_end[0][1],
                                        ))    
            return False

print("使用方法:\n共选取两个点,\n第一个点为起点,第二个点为终点\n注意:点必须为左上角到右下角的选取")
listenerMouse = mouse.Listener(on_click=on_click)  # 监听鼠标
listenerMouse.start()  # 开始
listenerMouse.join()  # 添加监听器
listenerMouse.stop()  # 结束


代码改进


改进代码如下:

from threading import Thread
from pynput import mouse, keyboard
from tkinter import *
import pyautogui
import pyscreeze
import datetime
import os

# 设计异步操作
def async_call(fn):
    def wrapper(*args, **kwargs):
        Thread(target=fn, args=args, kwargs=kwargs).start()
    return wrapper


# 封装截图功能
@async_call
class screen:
    def __init__(self) -> None:
        self.joints = [] # 节点列表
        self.p = True # 控制鼠标监听的开关
        self.listener() # 开始监听
        self.win_x, self.win_y = pyautogui.size()  # 获取屏幕分辨率
        self.tk = Tk() # 创建窗口
        self.tk.resizable(width=False, height=False)  # 禁止更改窗口大小
        self.tk.geometry("{}x{}".format(self.win_x,self.win_y)) # 设置窗口大小和显示位置
        self.tk.configure(bg="#808080") # 设置窗口背景颜色
        self.tk.attributes("-alpha", 0.5) # 设置窗口透明度
        self.tk.attributes('-topmost', 'true') # 置顶窗口
        self.tk.overrideredirect(True) # 关闭窗口标题栏

        self.canvas = Canvas(self.tk, width=self.win_x, height=self.win_y) # 创建画布
        self.canvas.pack() # 封装画布
        self.tk.bind('', self.quit) # 结束截图
        self.tk.bind('', self.save) # 保存截图
        self.canvas.bind("", self.on_mouse_drag) # 绘制矩形选个框
        self.tk.mainloop() # 保持窗口开启    
    def quit(self, event):
        self.p = False
        self.tk.destroy() # 退出窗口
    def save(self, event):
        self.p = False
        self.tk.destroy() # 退出窗口
        path = "screen"  # 相对路径
        if path not in os.listdir("C:/Users/Public/Downloads"):  # 判断相对路径文件夹是否存在
            os.mkdir("C:/Users/Public/Downloads/"+path) # 创建文件夹
        # 获取当前时间
        nowDatatime = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%d-%H%M%S")  

        # 调整节点
        if self.joints[1][0]<self.joints[0][0]:
            self.joints[1][0],self.joints[0][0]=self.joints[0][0],self.joints[1][0]
        if self.joints[1][1]<self.joints[0][1]:
            self.joints[1][1],self.joints[0][1]=self.joints[0][1],self.joints[1][1]
        # 截图
        pyscreeze.screenshot("C:/Users/Public/Downloads/screen/{}.png".format(nowDatatime), 
                                    region=(self.joints[0][0],
                                    self.joints[0][1],
                                    self.joints[1][0]-self.joints[0][0],
                                    self.joints[1][1]-self.joints[0][1],
                                    ))   
    def on_mouse_drag(self, event):
        self.canvas.delete("crop_rectangle") # 删除上一步绘画
        self.current_x = event.x # 临时变量,鼠标横轴
        self.current_y = event.y # 临时变量,鼠标纵轴
        self.canvas.create_rectangle(self.joints[0][0], self.joints[0][1], self.current_x, self.current_y, fill="gray", outline="red", tags="crop_rectangle") # 绘制矩形所选框

    # 设置按下或放下鼠标时操作
    def on_click(self, x, y, button, pressed):
        if not self.p:
            return self.p # self.p为false是停止监听
        if len(self.joints) == 2:self.joints=[] # 节点数为2时重置
        self.joints.append([x,y]) # 向节点列表添加节点
        # print(self.joints) # 输出节点数值

    # 设计鼠标监听
    @async_call # 异步操作防止监听事件影响画布加载
    def listener(self):
        listenerMouse = mouse.Listener(on_click=self.on_click)  # 监听鼠标
        listenerMouse.start()  # 开始    
        listenerMouse.join()  # 添加监听器
        listenerMouse.stop()  # 结束
# 使用说明
print("使用说明:\n程序启动后按++s进行截图,enter为保存,esc为退出截图\n截图会被保存在C:\\Users\\Public\\Downloads\\screen中")
# 绑定热键监听键盘事件
with keyboard.GlobalHotKeys({
    "++s":lambda:screen()
}) as l:
    l.join()


效果如下:


源码地址:

https://github.com/yhtbyr/AITRIPS/blob/main/ScreenCaptureTool.py


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表