前言
今天我看了一下自己的文件夹,发现了自己写了许多似乎很无聊的代码。于是乎,一个想法油然而生:“生活已经很无聊了,不如再无聊一点叭”。
说干就干,那就开一个专题,我们称之为kimol君的无聊小发明。
妙…啊~~~
今天要做的东西,就是用python写一个截屏工具。想必大家平时截屏的时候很多都是用的微信的ALT+A或者是WINDOWS自带的截屏软件。作为技术宅的我,怎么总是用别人的东西呢?
看我的,上图:
效果还阔以,好歹这个小猫咪截出来也是有模有样的~
一、技术实现
1. 相关库
在python中可以实现截图的库有很多,这里我用的是pyautogui,它可以对指定区域进行截屏:
1
|
import pyautogui
|
而界面部分(截屏的框选等)采用了tkinter库:
2. 定义窗口
定义一个透明的窗口,让它的大小与屏幕一样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
root = tk.Tk()
root.overrideredirect( True ) # 隐藏窗口的标题栏
root.attributes( "-alpha" , 0.1 ) # 窗口透明度10%
root.geometry( "{0}x{1}+0+0" . format (root.winfo_screenwidth(), root.winfo_screenheight()))
root.configure(bg = "black" )
注:alhpa参数用于设定透明度;geometry函数用于设定窗口大小;
创建一个子窗口,用于显示框选区域:
# 再创建1个Canvas用于圈选
cv = tk.Canvas(root)
x, y = 0 , 0
xstart,ystart = 0 , 0
xend,yend = 0 , 0
rec = ''
|
注:alhpa参数用于设定透明度;geometry函数用于设定窗口大小;
创建一个子窗口,用于显示框选区域:
1
2
3
4
5
6
|
# 再创建1个Canvas用于圈选
cv = tk.Canvas(root)
x, y = 0 , 0
xstart,ystart = 0 , 0
xend,yend = 0 , 0
rec = ''
|
3. 绘制工具条
绘制一个工具条,方便后续增加功能。讲道理目前来说这个就是个鸡肋(可以省去),但是如果后续还想晚上功能的话,会很有帮助。
1
2
3
4
5
6
7
8
|
canvas = tk.Canvas(root)
canvas.configure(width = 300 )
canvas.configure(height = 100 )
canvas.configure(bg = "yellow" )
canvas.configure(highlightthickness = 0 ) # 高亮厚度
canvas.place(x = (root.winfo_screenwidth() - 500 ),y = (root.winfo_screenheight() - 300 ))
canvas.create_text( 150 , 50 ,font = 'Arial -20 bold' ,text = 'ESC退出,假装工具条' )
1234567
|
4. 定义事件函数
监听鼠标和键盘事件,实时监控框选区域和截屏,具体的事件有:
1
2
3
4
5
6
7
8
|
# 绑定事件
canvas.bind( "<B1-Motion>" , move) # 鼠标左键移动->显示当前光标位置
root.bind( '<Escape>' ,sys_out) # 键盘Esc键->退出
root.bind( "<Button-1>" , button_1) # 鼠标左键点击->显示子窗口
root.bind( "<B1-Motion>" , b1_Motion) # 鼠标左键移动->改变子窗口大小
root.bind( "<ButtonRelease-1>" , buttonRelease_1) # 鼠标左键释放->记录最后光标的位置
root.mainloop()
|
监听鼠标光标位置:
1
2
3
4
5
6
7
8
9
|
def move(event):
global x, y ,xstart,ystart
new_x = (event.x - x) + canvas.winfo_x()
new_y = (event.y - y) + canvas.winfo_y()
s = "300x200+" + str (new_x) + "+" + str (new_y)
canvas.place(x = new_x - xstart,y = new_y - ystart)
print ( "s = " , s)
print (root.winfo_x(), root.winfo_y())
print (event.x, event.y)
|
创建子窗口:
1
2
3
4
5
6
7
8
9
10
11
12
|
def button_1(event):
global x, y ,xstart,ystart
global rec
x, y = event.x, event.y
xstart,ystart = event.x, event.y
print ( "event.x, event.y = " , event.x, event.y)
xstart,ystart = event.x, event.y
cv.configure(height = 1 )
cv.configure(width = 1 )
cv.config(highlightthickness = 0 ) # 无边框
cv.place(x = event.x, y = event.y)
rec = cv.create_rectangle( 0 , 0 , 0 , 0 ,outline = 'red' ,width = 8 ,dash = ( 4 , 4 ))
|
改变子窗口大小:
1
2
3
4
5
6
7
|
def b1_Motion(event):
global x, y,xstart,ystart
x, y = event.x, event.y
print ( "event.x, event.y = " , event.x, event.y)
cv.configure(height = event.y - ystart)
cv.configure(width = event.x - xstart)
cv.coords(rec, 0 , 0 ,event.x - xstart,event.y - ystart)
|
松开鼠标,记录最后的光标位置:
1
2
3
|
def buttonRelease_1(event):
global xend,yend
xend, yend = event.x, event.y
|
截屏并保存图片:
1
2
3
4
5
6
7
|
def button_3(event):
global xstart,ystart,xend,yend
cv.delete(rec)
cv.place_forget()
img = pyautogui.screenshot(region = [xstart,ystart,xend - xstart,yend - ystart]) # x,y,w,h
img.save( 'screenshot.png' )
sys_out( None )
|
退出程序:
1
2
|
def sys_out(even):
root.destroy()
|
二、后续改进
这个还有很多可以改进的地方。
- 截图的时候会有dos窗口遮挡:这个解决办法由很多,类似后台启动,或者将.py编译为可执行文件等等;
- 使用不方便,为了截图还的运行代码:废话!!!当然很不方便呀,不然怎么说是个无聊的小发明呢。但是!!!它也不是一无事处,可以考虑把它放到后台运行。同样可以利用快捷键来唤醒它并完成截图。
- 功能单一:这只是一个很简单的demo,既然可以截屏了,那么我们离录屏还远吗?(正如本文开头的动图,右上角晃晃几个大字“ApowerREC”,不给钱休想去掉,哼~)那么,我们为何不自己写一个呢?
写在最后
最后,感谢各位大大的耐心阅读~
到此这篇关于如何使用python写截屏小工具的文章就介绍到这了,更多相关python截屏小工具内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/41280a/archive/2020/09/29/13749874.html