使用Python保存屏幕截图(不使用PIL)
在极客学院讲授《使用Python编写远程控制程序》的课程中,涉及到查看被控制电脑屏幕截图的功能。,如果使用PIL,这个需求只需要三行代码:,但是考虑到被控端应该尽量的精简,对其他模块尽量少的依赖,这样才能比较方便的部署,因此我考虑能否有一种方法,不依赖PIL来实现截图的功能。,由于被控端使用了win32api, 因此有一个方法:,这个方法可以模拟键盘的按键动作。因此,解决方法就比较的明显了:,第一步非常的简单,实用win32api 和 win32con,两行代码就能实现:,其中win32con这个库里面包含了很多定义好的和Windows相关的常量,而VK_SNAPSHOT就是Print Screen键的键位码。后面的数字0表示截取整个屏幕。如果改成数字1,表示截取当前窗口。,那么现在问题来了,在不实用PIL的情况下,如何将剪贴板你们的图片保存到本地?,win32api有一个模块 win32clipboard 是负责剪贴板相关的操作。它有一个方法:,这个方法可以从剪贴板里面读取数据。但是需要指定数据的格式。从这里可以查看到更多的标准剪贴板格式(Standard Clipboard Formats).,一开始我使用的formats是CF_BITMAP,程序返回的是一串整数,怀疑应该是一个内存地址。这也和这个format的描述:,是一致的,它是一个handle。,我也尝试过CF_TIFF, 不过程序直接报错了,可见我使用Print Screen截图以后,剪贴板里面的图片格式并不是TIFF。,经过查阅其他资料,我最后确定使用了CF_DIB。,这个描述说明,CF_DIB返回的是一个内存对象,包含了BIT格式图片的信息。经过测试使用:,以后,可以得到一个很大的字符串。显然这个字符串就是图片的内容了。但是当我把这个字符串写入到bmp格式的文件后,却发现图片无法打开。,在StackOverflow上,我遇到了一个非常好的老先生: Mr. martineau他为了解答了问题,并给我提供了解决办法。以下内容翻译自martineau先生的回答,原文请戳->http://stackoverflow.com/a/35885108/3922976,经过测试,这一段代码成功的实现了读取剪贴板的图片并保存到本地。,这段代码使用ctypes库来实现指针的功能,从而在内存中操作数据。这里定义了两个结构体,BITMAPFILEHEADER
和BITMAPINFOHEADER
,于是,使用sizeof获取到了他们的大小。那么使用指针,从使用GetClipboardData()
获取到的数据的头部开始移动,分别移动这两个结构体的大小,也就获取到了这两个结构体在内存中的数据。,代码中使用了memmove
和memset
两个内存操作的方法。从ctypes的官方文档上,我们可以看到这两个方法有如下的定义:,所以可以看出,代码里面的:,从内存中拷贝出来了BITMAPINFOHEADER
这么大的一块的数据,并保存到了bmih
这个变量中。,这一段在内存中开辟出了BITMAPFILEHEADER
这么大一块区域,并全部填充为0.,这一行代码使用了位操作。首先ord('B')
的值为66,换成二进制就是1000010
;ord('M')
的值为77,换成二进制就是1001101
,然后向左移动8位,得到100110100000000
,这个值再与1000010
取位或,得到100110101000010
。,最后,使用:,
2. 本站不保证所提供所有下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理,有奖励!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或教程,您可以投稿发布,成功分享后有RB奖励和额外RMB收入!
磊宇堂正在使用的服务器 维护管理由磊宇云服务器提供支持
磊宇堂 » 使用Python保存屏幕截图(不使用PIL)