当前位置:   article > 正文

python 使用 adb 截屏_pythonadb 截屏

pythonadb 截屏

第一版:

  1. adb_cmd.adb_cmd("shell screencap -p /data/local/tmp/tmp.png")
  2. time.sleep(0.2)
  3. adb_cmd.adb_cmd("pull /data/local/tmp/tmp.png " + path)
  4. time.sleep(1)
  5. adb_cmd.adb_cmd("shell rm /data/local/tmp/tmp.png")

具体过程是先截屏保存在手机中,在使用pull指令保存到本地,这样做比较耗时,考虑优化;

使用管道直接存到本地,去掉保存在手机中的过程;

第二版:

  1. if device is None:
  2. cmd = f'adb shell screencap -p > {tmp}'
  3. else:
  4. cmd = f'adb -s {device} shell screencap -p > {tmp}'
  5. ret = os.popen(cmd)

使用管道重定向直接存在本地,但这样保存的图片不能直接使用,直接对比文件:

 

 上图是正常的图片文件,下图是异常的图片文件,可以看出所有0a都转换成了0d 0a,当作文本格式自动将换行符转换成回车换行了;重新转换回来:

  1. file = open(tmp, 'rb')
  2. find = False
  3. for i in range(size):
  4. data = file.read(1)
  5. if data == '': break
  6. if find:
  7. if data != b'\n':
  8. w.write(b'\r')
  9. find = False
  10. if data == b'\r':
  11. find = True
  12. continue
  13. w.write(data)

运行发现转换后的图片不全,判断是截图指令还未执行完毕,判断临时文件长度没有变化才开始转换

  1. l = 0
  2. c = 0
  3. while True:
  4. size = os.path.getsize(tmp)
  5. if size != 0 and size == l: break
  6. l = size
  7. c += 1
  8. if c > 10: break
  9. time.sleep(0.2)

完整第二版代码:

  1. tmp = path_name('tmp',0)
  2. if device is None:
  3. cmd = f'adb shell screencap -p > {tmp}'
  4. else:
  5. cmd = f'adb -s {device} shell screencap -p > {tmp}'
  6. print(cmd,end='...')
  7. w = open(path, 'wb')
  8. ret = os.popen(cmd)
  9. time.sleep(1)
  10. l = 0
  11. c = 0
  12. while True:
  13. size = os.path.getsize(tmp)
  14. if size != 0 and size == l: break
  15. l = size
  16. c += 1
  17. if c > 10: break
  18. time.sleep(0.2)
  19. print(c,size)
  20. file = open(tmp, 'rb')
  21. find = False
  22. for i in range(size):
  23. data = file.read(1)
  24. if data == '': break
  25. if find:
  26. if data != b'\n':
  27. w.write(b'\r')
  28. find = False
  29. if data == b'\r':
  30. find = True
  31. continue
  32. w.write(data)
  33. w.close()
  34. file.close()
  35. print(path)
  36. #time.sleep(1)
  37. return path

相较第一版,速度有较大的提升,但感觉还是不太理想,图片数据临时保存到硬盘上,再读入处理,效率还是有点低,可否直接在内存中处理,去掉保存临时文件的步骤。尝试过直接读取popen管道数据,但是会报编码错误;在网上一通查找,找到subprocess.Popen方法;

第三版代码:

  1. cmd = []
  2. cmd.append('adb')
  3. device = sqlite.get_device()
  4. if not device is None:
  5. cmd.append('-s')
  6. cmd.append(device)
  7. cmd.append('shell')
  8. cmd.append('screencap')
  9. cmd.append('-p')
  10. print(cmd,end='...')
  11. p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
  12. #p.wait()
  13. output = p.communicate()[0]
  14. #print(output)
  15. size = len(output)
  16. print('size',size)
  17. #file = open(tmp, 'rb')
  18. w = open(path, 'wb')
  19. find = False
  20. c = 0
  21. for i in range(size):
  22. data = output[i].to_bytes(1,byteorder='little', signed=False) #file.read(1)
  23. if c < 10:
  24. print(data,end=' ')
  25. c += 1
  26. if data == '': break
  27. if find:
  28. if data != b'\n':
  29. w.write(b'\r')
  30. find = False
  31. if data == b'\r':
  32. find = True
  33. continue
  34. w.write(data)
  35. w.close()

感觉这个方法是最优的了,有两个地方需要注意:

output = p.communicate()[0]

p.communicate()返回的是数组,第一项才是输出;

data = output[i].to_bytes(1,byteorder='little', signed=False)

返回的是int类型数组,需要转换成byte

  1. if c < 10:
  2. print(data,end=' ')

打印了前10个字节,确定还是存在回车换行的问题,还是需要进行转换。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/474952
推荐阅读
相关标签
  

闽ICP备14008679号