一、起因

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

为什么卡住了呢,简单说,因为我需要获取截屏的数据,所以就要找一些能截屏的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. leetcode@ [327] Count of Range Sum (Binary Search)

    https://leetcode.com/problems/count-of-range-sum/ Given an integer array nums, return the number of ...

  2. hello, angular

    开始系统学习一下angular!首先是hello world.根据官网给出的例子,我们一下做出下面这个东西: <!DOCTYPE html> <html ng-app> < ...

  3. HDU 5792 World is Exploding (树状数组)

    World is Exploding 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5792 Description Given a sequence ...

  4. UVA 315 315 - Network(求割点个数)

     Network  A Telephone Line Company (TLC) is establishing a new telephone cable network. They are con ...

  5. #pragma comment使用

    编程经常碰到,理解的总不是很透彻,在这里查阅资料总结一下! 在编写程序的时候,我们常用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作. #pragma once : 这是一个 ...

  6. Connection对象连接加密2

    一般情况下,大多数人习惯于将数据库连接写在web.config上里面,理论上讲,将明文存放在该文件里面是安全的,因为web.config文件是不允许被客户端下载,但一旦该文件泄漏出去,哪怕是很短的时间 ...

  7. springMVC部署

      一.导入springMVC所需要的jar包   下载地址:http://repo.spring.io/release/org/springframework/spring/   二.springM ...

  8. swift 个人笔记

    swift是现代编程语言的综合体,灵活而强大. //http://www.cocoachina.com/newbie/basic/2014/0604/8675.html //语法var 变量,let ...

  9. 怎么SDCard上的获取相册照片

    private String getRealPathFromURI(Uri contentUri) { Cursor cursor = null; String result = contentUri ...

  10. Ogre分层渲染 (转)

    Ogre分层渲染 转载请注明出处!http://www.cnblogs.com/pulas 在超大的场景中,如果既想看到近处的物体,又想看到很远的物体,则必须把相机的远近裁剪面距离设得很大.远近裁剪面 ...