一、起因

最近想做个小外挂玩玩,技术倒是不难,就是通过图片匹配加上一些判断方法来刷分。但是在最不起眼(却最容易出问题)的准备阶段卡住了。

为什么卡住了呢,简单说,因为我需要获取截屏的数据,所以就要找一些能截屏的Python库。本来以为很简单,但是实际配置起来却。。。

PIL,不支持Mac截图

autopy,mac os安装不上,经过我去官方的issue搜索,发现很多人遇到同样的问题,然后,官方没有给出解决办法,也就是说不能用

pyscreenshot,安装很费劲,因为依赖其他的Python UI库,好不容易安装好wxpython之后,发现截图是黑屏。。。

看到这里可能你会问了,为什么不用系统自带的截图工具呢?

这个其实我也想到了,Mac确实自带截图工具,并且可以命令行运行,使用Python的os.system("xxx")就可以。但是这个方法有一个缺点,就是截图会保存到本地。因为后面要用PIL处理图片,所以整个过程就是:截图--存到本地--PIL从文件读图。大家应该都知道,内存和硬盘的速度是天差地别。。。这个存--取的步骤会增加很多时间。虽然也就是几百毫秒,但是你要知道,一个外挂最起码一秒也要截好记张图,才能及时做出反应。所以这个速度是不能接受的。

然后呢。。。直接进入主体,我使用了pyobjc。

二、pyobjc简介

什么是pyobjc,如果你不愿意百度的话,那我用一句话介绍一下。

pyobjc就是用Python来写objective-c程序。

那什么又是objective-c呢?

objective-c就是专门写ios程序的语言。

懂了吧,pyobjc其实就是一个桥梁,让我们可以用Python写ios的程序,就像你在Windows下面可以用Windows的各种API一样,这个东西让你可以在mac os x环境下面做任何事。

三、波澜起伏

pyobjc装好了,尝试import一个库,没问题。然后就是截图了。

因为objective-c我不会啊!所以只能Google了。

好吧,Google了一下(别问我为什么不用百度!)找到一篇用pyobjc截图的教程

这个教程里面的capture就是截图函数。我们不需要关心。直接看最后。。。好吧,pngcanvas是什么东西?

按照代码注释里的网址,发现是一个保存图片的小插件。

把插件代码存到本地以后,运行了一下,可以得到图片了!然后。。。等等,怎么截一个图要十几秒????!!!!

仔细研究发现,其实截图的时间很短,只有几十毫秒。真正耗时的是把图存到本地。

然后。。别忘了,我们是要在PIL中使用图,所以思路出来了,把数据转换成PIL的Image。

怎么转换呢?

先看看他的代码是怎么转换的吧:

from pngcanvas import PNGCanvas
c = PNGCanvas(sp.width, sp.height)
for x in range(sp.width):
for y in range(sp.height):
c.point(x, y, color = sp.pixel(x, y)) with open("/Users/selfdir/Documents/littlerabbit/text.png", "wb") as f:
f.write(c.dump())

好吧,虽然不知道PNGCanvas的用法,但是看也能看懂了,他是一个一个像素填充的。

那么。。。Google一下发现PIL有一个Image.putpixel()方法,直接动手修改:

for x in range(sp.width):
for y in range(sp.height):
img1.putpixel((x,y),sp.pixel(x, y))

img1.save()

好了,运行一下~~成功!。。。等等,时间还是很长啊,8秒??!!

好吧。。。仔细分析一下,这样一个一个像素填充肯定是很慢的嘛。。。那么有没有办法直接生成Image呢。

继续Google。。。发现PIL有个Image.fromstring()函数,可以直接把字符串转换成Image~~赶快使用:

img1 = Image.fromstring("RGBA", (sp.width, sp.height), xxxx) 
img1.save(...)

哈哈成功~~时间也变成一百多毫秒了。然后。。。等等(你到底要等多少次= =)!怎么图片颜色不对劲啊。。。。

研究发现,是图片的模式不对。capture获取的图片数据是按照BRGA的顺序来储存的,但是PIL是使用RGBA生成图片,自然颜色就不对了。。。

继续Google!!!

直接上最终解决代码:

img1 = Image.fromstring("RGBA", (sp.width, sp.height), xxxx)
b, g, r, a= img1.split()
img1 = Image.merge("RGBA", (r, g, b, a))
img1.save(...)

先split再merge,实现数据换位。

终于成功了!!

然后我们注释掉save语句,再次运行,发现截图+转换一共只需要不到40ms的时间,已经很快了,足够做外挂了~~~

四、总结

好吧,啰嗦了半天终于写完了。

看着很简单,但是其实我是搞了一天才搞定啊。。。。真的是各种麻烦。还好最后搞定了~记录下来希望能帮助到你。

[辛酸历程]在Mac中使用Python获取屏幕截图的更多相关文章

  1. 如何在Mac中配置Python虚拟环境,踩了好多坑

    如何在Mac中配置Python虚拟环境 1.安装virtualenv pip3 install virtualenv 2.安装virtualenvwrapper pip3 install virtua ...

  2. 极速在mac中安装python开发环境

    mac开发环境的安装: brew: 包管理工具{ 安装:ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/in ...

  3. 在Mac中安装python,配置python环境

    参考链接:http://blog.justbilt.com/2014/07/02/setup_python_on_mac/ 其实跟windows差不多,就是在python官网下载特定版本的python ...

  4. Mac中的Python安装selenium,结合chrom及chromdriver使用

    一.安装selenium 1.在终端通过命令安装 pip3 install -U selenium 二.准备环境 1.在电脑中安装谷歌浏览器chrom,和下载估计浏览器驱动chromdriver,以下 ...

  5. MAC中查看Python安装路径

    [admin@admindeMac:~]which  Python /usr/bin/Python

  6. 为什么说 Python 是数据科学的发动机(一)发展历程(附视频中字)

    为什么说 Python 是数据科学的发动机(一)发展历程(附视频中字) 在PyData Seattle 2017中,Jake Vanderplas介绍了Python的发展历程以及最新动态.在这里我们把 ...

  7. python获取本机IP、mac地址、计算机名

    在python中获取ip地址和在php中有很大不同,在php中往往比较简单.那再python中怎么做呢? 我们先来看一下python 获得本机MAC地址: 1 2 3 4 import uuid de ...

  8. Python - 获取本机IP地址、Mac地址

    Python - 获取本机IP地址.Mac地址 在python中获取ip地址和在php中有很大不同,在php中往往比较简单.那再python中怎么做呢? 直接看代码: # Python - 获取本机I ...

  9. Python 获取 网卡 MAC 地址

    /*********************************************************************** * Python 获取 网卡 MAC 地址 * 说明: ...

随机推荐

  1. linux vim用法总结

    1.跳转到指定行 编辑模式下:输入  ngg或nG(n代表行数) 命令模式下:输入  :n(n代表行数) 2.查找命令 命令模式下输入 / 后面加上查找的内容 例如    :/name     (查找 ...

  2. SRM DIV1 500pt DP

    SRM 501 DIV1 500pt SRM 502 DIV1 500pt SRM 508 DIV1 500pt SRM 509 DIV1 500pt SRM 511 DIV1 500pt SRM 5 ...

  3. 【转】Nginx系列(二)--模块化

    原博文出于: http://blog.csdn.net/liutengteng130/article/details/46700977  感谢! 高度模块化的设计设Nginx架构的基础.在Nginx中 ...

  4. Oracle的回收站和闪回查询机制(二)

    上一篇中讲诉了Oracle中一些闪回查询(Flashback Query),这是利用回滚段信息来恢复一个或一些表到以前的一个时间点(一个快照).要注意的是,Flashback Query仅仅是查询以前 ...

  5. Gym 100507J Scarily interesting! (贪心)

    Scarily interesting! 题目链接: http://acm.hust.edu.cn/vjudge/contest/126546#problem/D Description This y ...

  6. Linux(Centos)全自动异地备份数据(WEB+Mysql)

    文章开始之前,先问下各位站长一个问题:什么东西对于站长是十分重要的?其实对于站长而言,很多东西都是很重要的.但我们现在排除外在因素,把范围缩小到网站系统本身,哪些是非常重要的呢?网站数据就是其中之一了 ...

  7. C#中的ref和out的区别

    转载原地址 http://www.cnblogs.com/gjahead/archive/2008/02/28/1084871.html ref和out的区别在C# 中,既可以通过值也可以通过引用传递 ...

  8. 12 为何使用Html5+CSS3

    一:大多浏览器支持,低版本也没问题 我看点这方面的资料,是为了做手机应用网站(有三个方案,这个是备用方案),可以开发响应式网站,可以脱离开发平台进行跨平台. 在Html5网页中引入Modernizr, ...

  9. oracle对序列的操作

    select t.*, t.rowid from tbl_type t order by t.id desc Select SEQ_TBL_TYPE_ID.NextVal From Dual; ; ; ...

  10. .Net 揭密--JIT怎样运行你的代码

    方法调用: 第一部分 (普通调用) 译者:我们都知道.NET托管代码如C#.VB.NET写成的代码,都是先被编译成中间语言(IL,Intermediate Language,在运行时,再由即时编译器( ...