实现思路是先获取到当前最上面活动的窗口信息,然后提取该窗口的名称信息。
之后获取窗口的坐标信息,即左上角的开始坐标及右下角的结束坐标。最后直接截图并将截图的图片进行展示。
其中用到了两个第三方模块,分别是win32gui和Pillow,安装命令如下:
1
2
|
pip install Pillow pip install win32gui |
将其中使用到的三个非标准库导入进来。
1
2
3
|
from win32gui import * # 操作windows窗口 from PIL import ImageGrab # 操作图像 import win32con # 系统操作 |
初始化一个set列表存放所有活动窗口名称,使用set类型的目的是保证所有活动窗口名称的唯一性。
1
|
names = set () |
编写get_window_title函数,获取当前的所有活动窗口对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def get_window_title(window, nouse): ''' 获取窗口标题函数 :param window: 窗口对象 :param nouse: :return: ''' if IsWindow(window) and IsWindowEnabled(window) and IsWindowVisible(window): names.add(GetWindowText(window)) EnumWindows(get_window_title, 0 ) list_ = [name for name in names if name] for n in list_: print ( '活动窗口: ' , n) |
输入自己想要截图的窗口名称作为当前窗口,然后提取到需要截图的窗口对象。
1
2
3
4
5
|
name = input ( '请输入需要截图的活动窗口名称: \n' ) window = FindWindow( 0 , name) # 根据窗口名称获取窗口对象 ShowWindow(window, win32con.SW_MAXIMIZE) # 将该窗口最大化 |
获取该窗口的坐标信息,开始坐标信息和结束坐标信息。
1
2
3
4
|
x_start, y_start, x_end, y_end = GetWindowRect(window) # 坐标信息 box = (x_start, y_start, x_end, y_end) |
调用ImageGrab.grab()函数实现对窗口的截图操作。
1
|
image = ImageGrab.grab(box) |
在完成截图之后展示一下截图的效果,如果不需要展示的话就不需要添加这行代码了。
1
|
image.show() # 图片展示,如果截完图需要展示则放开此项 |
最后一步,将截图好的图片保存下来。
1
2
3
|
image.save( 'target.png' ) print ( '截图已经保存完成!' ) |
上面整个的python截图操作就实现了
补充
当然Python中还有更多方法实现窗口截图
方法一:使用pyautogui方法实现截屏
1
2
3
4
5
6
7
8
9
10
11
|
import pyautogui import cv2 import numpy as np img = pyautogui.screenshot(region = [ 300 , 50 , 200 , 100 ]) # 分别代表:左上角坐标,宽高 #对获取的图片转换成二维矩阵形式,后再将RGB转成BGR #因为imshow,默认通道顺序是BGR,而pyautogui默认是RGB所以要转换一下,不然会有点问题 img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR) cv2.imshow( "截屏" ,img) cv2.waitKey( 0 ) |
优点:
- 方便快捷,容易写核心部分就一行.
- 速度快0.04s左右,基本可以达到实时截屏的效果。
- 可以自由确定截屏区域
缺点:
但是不能指定获取程序的窗口,因此窗口也不能遮挡。
方法二:使用PyQt方法实现截屏
a.获取窗口的句柄,也就是目标窗口名title
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import win32gui hwnd_title = dict () #创建字典保存窗口的句柄与名称映射关系 def get_all_hwnd(hwnd, mouse): if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd): hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)}) win32gui.EnumWindows(get_all_hwnd, 0 ) for h, t in hwnd_title.items(): if t! = "": print (h, t) |
注:程序会打印所有窗口的hwnd和title,有了title就可以进行截图了。
b.使用PyQt5截屏核心程序
1
2
3
4
5
6
7
8
9
|
from PyQt5.QtWidgets import QApplication import win32gui import sys #这个是截取全屏的 hwnd = win32gui.FindWindow( None , 'C:/Windows/system32/cmd.exe' ) app = QApplication(sys.argv) screen = QApplication.primaryScreen() img = screen.grabWindow(hwnd).toImage() img.save( "screenshot.jpg" ) |
注:如果想截取特定的窗口,只需要将C:/Windows/system32/cmd.exe换成上一个程序中打印的title,并且保证那个窗口没有被你最小化即可
优点:
方便快捷,容易写核心部分就一行.
速度快0.04s左右,基本可以达到实时截屏的效果。
可以自由确定要截屏的窗口
缺点:
不可以自由确定截屏区域
c.使用PyQt5截屏用Mat格式显示的核心程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
def convertQImageToMat(incomingImage): ''' Converts a QImage into an opencv MAT format ''' # Format_RGB32 = 4,存入格式为B,G,R,A 对应 0,1,2,3 # RGB32图像每个像素用32比特位表示,占4个字节, # R,G,B分量分别用8个bit表示,存储顺序为B,G,R,最后8个字节保留 incomingImage = incomingImage.convertToFormat( 4 ) width = incomingImage.width() height = incomingImage.height() ptr = incomingImage.bits() ptr.setsize(incomingImage.byteCount()) arr = np.array(ptr).reshape(height, width, 4 ) # Copies the data # arr为BGRA,4通道图片 return arr from PyQt5.QtWidgets import QApplication import win32gui import sys import cv2 import numpy as np hwnd = win32gui.FindWindow( None , '剑士之魂中文版小游戏,在线玩,4399小游戏 - 360安全浏览器 13.1' ) app = QApplication(sys.argv) screen = QApplication.primaryScreen() img = screen.grabWindow(hwnd).toImage() img = convertQImageToMat(img) #将获取的图像从QImage转换为RBG格式 cv2.imshow( "asd" ,img) #imshow cv2.waitKey( 0 ) |
到此这篇关于Python实现超快窗口截图功能详解的文章就介绍到这了,更多相关Python窗口截图内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/lwsbc/p/16271504.html