python学习——截图工具编写

学习一门语言最好的方法便是实践,想要拿Python写一个截图工具,网上一搜资料果然已经很多,前辈们都已经做的很到位了。现在就一步步来学习一下:

首先学习截图整个桌面的方法,可以使用Python中的PIL(Python Imaging Library)库里边的ImageGrab.grab()函数来获取截图。然后使用save()函数将图片保存下来。简单的不能再简单了,源码如下:

 

from PIL import ImageGrab

pic = ImageGrab.grab()

pic.save("D:\\picture.jpg")


这样我们便可以将整个桌面截图保存在D盘根目录下。So easy。另外关于图片存储格式,使用save()函数保存时路径中文件格式为jpg、bmp、png均可,亲测可行,bmp格式存储空间最大,理论上来说数据失真率也最低。

 

下面我们考虑如何将当前窗口截图保存,ImageGrab.grab()函数没有参数时默认将整个屏幕截图,当我们给它传递一个矩形的坐标时,它便可以将制定矩形进行截图。同时这里我们需要在python中调用win32的GUI函数来获取当前窗口的句柄、进而获取当前窗口的位置坐标。同时,我们需要在python中定义一个结构体来存储获取的坐标值,于是我们又学习了python中结构体的定义以及win32 gui函数调用的方法,源码如下:

 

import win32gui

from ctypes import *

import ctypes

from PIL import ImageGrab

import win32api,win32con

import pyHook

import pythoncom



#定义结构体,存储当前窗口坐标

class RECT(ctypes.Structure):

    _fields_ = [('left', ctypes.c_int),

                ('top', ctypes.c_int),

                ('right', ctypes.c_int),

                ('bottom', ctypes.c_int)]

rect = RECT()

HWND = win32gui.GetForegroundWindow()#获取当前窗口句柄

ctypes.windll.user32.GetWindowRect(HWND, ctypes.byref(rect))#获取当前窗口坐标

coordinate = (rect.left+2, rect.top+2, rect.right-2, rect.bottom-2)#转换为预截图窗口坐标

pic = ImageGrab.grab(coordinate)#截图

pic.save("D:\\321.jpg")#保存

 

其中ctypes中的byref()方法是用来返回结构体的指针,从而将窗口坐标存储在结构体中。

在实现了全屏截图以及指定窗口截图以后,我们便需要考虑如何实现指定范围截图。我的思路是利用pyHook工具包实现对鼠标事件的监听,在鼠标左键按下时,记录一个坐标,鼠标左键抬起时再记录一个坐标,于是便可以确定整个所要截图区域的矩形坐标,再使用ImageGrab.grab(coordinate)函数实现截图。源码如下:

 

coordinate = [1,1,1,1]

#监听键盘事件

def on_mouse_event(event):

    if event.MessageName == 'mouse left down':

        coordinate[0:2] = event.Position

    elif event.MessageName == 'mouse left up':

        coordinate[2:4] = event.Position

        win32api.PostQuitMessage()#退出监听循环

        pic = ImageGrab.grab(coordinate)

        pic.save("D:\\321.jpg")

    return True



hm = pyHook.HookManager()#创建一个钩子管理对象

hm.MouseAll = on_mouse_event#监听所有鼠标事件

hm.HookMouse()#设定鼠标钩子

pythoncom.PumpMessages()#进入循环,程序一直监听


这里我们在鼠标完成截图矩形坐标确定后,需要推出鼠标事件的监听。另外,目前存在一个问题,在用鼠标选取范围时会导致窗口焦点的改变,从而影响实际截图内容。因此可以进一步考虑先将屏幕锁定,再进行范围选定。或者也许可以先进行全屏截图,但仅显示而不保存,在显示的全屏截图上再进行区域截图。

 

恩,好了,一步步来,慢慢学习。菜鸟慢飞。



你可能感兴趣的:(python)