python 几种android截屏方式的学习与使用

screencap

screencap是Android的截屏工具。通过调用访问SurfaceFlinger服务或读取 /dev/graphics/fb0文件来实现屏幕截取。

方法:

  1. 直接获得图片的二进制数据,然后解析成相应的图片
import subprocessimport cv2import numpy as npdef get_screenshot():# 使用subprocess的Popen调用adb shell命令,并将结果保存到PIPE管道中        process = subprocess.Popen('adb shell screencap -p', shell=True, stdout=subprocess.PIPE)        # 读取管道中的数据        screenshot = process.stdout.read()        # 将读取的字节流数据的回车换行替换成'\n'        binary_screenshot = screenshot.replace(b'\r\n', b'\n')        # 使用numpy和imdecode将二进制数据转换成cv2的mat图片格式        img_screenshot = cv2.imdecode(np.frombuffer(binary_screenshot, np.uint8), cv2.IMREAD_COLOR)        return img_screenshot
  1. 将截图保存成png图片,然后pull到电脑端再读取
import subprocessimport cv2def adb(order):        return subprocess.Popen(order, shell=True, stdout=subprocess.PIPE, encoding='UTF-8').stdoutdef get_screenshot():adb('adb shell /system/bin/screencap -p /sdcard/screenshot.png') # 将截图保存到SDCard        adb('adb pull /sdcard/screenshot.png ./screenshot.png')# 将截图从手机拉取到电脑        adb('adb shell rm /sdcard/screenshot.png')# 删除手机端的截图image = cv2.imread('./screenshot.png') # 使用imread读取截图return image

appium

appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web应用和混合应用。
appium的安装就不在这里介绍了
关于appium安装配置时遇到的问题(传送门)

方法:

#-*- coding: UTF-8 -*-import osimport timeimport unittestimport base64import numpy as npimport cv2from appium import webdriver# 用于路径的转换PATH = lambda p: os.path.abspath(    os.path.join(os.path.dirname(__file__), p))desired_caps={}desired_caps['platformName']='Android'desired_caps['version']='6.0.0'desired_caps['deviceName']='MI MAX 2'#这是测试机的型号,可以查看手机的关于本机选项获得# desired_caps['app'] = PATH('mobileqq.apk')#被测试的App在电脑上的位置# print(desired_caps['app'])desired_caps['appPackage'] = 'com.tencent.mobileqq'desired_caps['appActivity'] = 'com.tencent.mobileqq.activity.SplashActivity'driver=webdriver.Remote('http://127.0.0.1:4725/wd/hub',desired_caps) # 访问端口,用于获取数据time.sleep(3)# 方法一:# 使用appium的get_screenshot_as_flie(image_save_path),直接将图片数据保存早电脑端# 然后通过cv2读取while True:    driver.get_screenshot_as_file(screen_save_path)    start = time.clock()    img = cv2.imread('./screenshot.png')    cv2.imshow('test', img)    cv2.waitKey(1)    # 方法二:# 使用appium的get_screenshot_as_base64()获得截屏的数据流# 然后通过base64解析数据格式# 使用numpy再次转换成uint8格式# 最后使用cv2自带的imdecode转换成mat格式while(True):    base64data = driver.get_screenshot_as_base64()    imgData = base64.b64decode(base64data)    nparr = np.fromstring(imgData,np.uint8)    img = cv2.imdecode(nparr, 1)    cv2.imshow('test', img)    cv2.waitKey(1)

minicap

minicap是开源项目STF(Smartphone Test Farm)中的一个工具,负责屏幕显示。
minicap的配置也不介绍了,网上有很多

方法:

网上提供了很多种连续获取图片的方式,但是很多时候,在获取一张图片之后就马上需要对其进行处理,这样的情况连续获取图片的方式并不合适
但是由于minicap本身传输的设定,手机端的minicap会源源不断的想socket传输图片信息,导致再次通过socket获得图片时,并不一定是当前的图片信息
这个时候采用的是重新断开socket连接的方式来再次获得图片

# 连接端口import socketimport cv2import numpy as np    def get_image()client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   client_socket.connect(('localhost', 7777))    readBannerBytes = 0    bannerLength = 24    readFrameBytes = 0    frameBodyLengthRemaining = 0    frameBody = ''    while True:        chunk = self.client_socket.recv(12000)        if len(chunk) == 0:            continue        cursor = 0        while cursor < len(chunk):         # 跳过前面24位baner信息             if (readBannerBytes < bannerLength):                cursor += 1                readBannerBytes += 1                           elif readFrameBytes < 4: # 在一开始的24位baner信息之后就是4位图片长度的信息                frameBodyLengthRemaining += (int(hex(chunk[cursor]), 16) << (readFrameBytes * 8))                cursor += 1                readFrameBytes += 1            else:                # 如果当前剩下的数据长度超过了图片还未读取的长度,说明这里包含了下一张图片的信息(由于不是连续读取,所以不考虑这些信息)                if len(chunk) - cursor >= frameBodyLengthRemaining:                    frameBody = frameBody + chunk[cursor:(cursor + frameBodyLengthRemaining)]                    if hex(frameBody[0]) != '0xff' or hex(frameBody[1]) != '0xd8':                        exit()                    img = np.array(bytearray(frameBody))                    img = cv2.imdecode(img, 1)                    self.client_socket.close()                    return img                else:                 # 这次数据的读取还未达到图片的数据的长度                     frameBody = bytes(list(frameBody) + list(chunk[cursor:len(chunk)]))                    frameBodyLengthRemaining -= (len(chunk) - cursor)                    readFrameBytes += len(chunk) - cursor                    cursor = len(chunk)if __name__ == '__main__':image = get_image()

更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. 读取android手机流量信息
  6. android 使用html5作布局文件: webview跟javascript交互
  7. Android(安卓)matrix 控制图片的旋转、缩放、移动
  8. Android(安卓)Resource介绍和使用
  9. "Failed to fetch URL https://dl-ssl.google.com/android/repos

随机推荐

  1. Android(安卓)RecyclerView网格布局
  2. Android左右滑动切换图片
  3. Android实现手势缩放图片
  4. Android上层怎样读写proc节点(示例)
  5. early_param("earlyprintk", setup_early
  6. android下为自己定义wifimanager类
  7. View 绘制机制 -- How Android(安卓)Draw
  8. 一维byte数组旋转
  9. 使用Notification发送消息通知
  10. Android(安卓)TextView 一些字体颜色、大