赞
踩
第一版:
- adb_cmd.adb_cmd("shell screencap -p /data/local/tmp/tmp.png")
- time.sleep(0.2)
- adb_cmd.adb_cmd("pull /data/local/tmp/tmp.png " + path)
- time.sleep(1)
- adb_cmd.adb_cmd("shell rm /data/local/tmp/tmp.png")
具体过程是先截屏保存在手机中,在使用pull指令保存到本地,这样做比较耗时,考虑优化;
使用管道直接存到本地,去掉保存在手机中的过程;
第二版:
- if device is None:
- cmd = f'adb shell screencap -p > {tmp}'
- else:
- cmd = f'adb -s {device} shell screencap -p > {tmp}'
- ret = os.popen(cmd)
使用管道重定向直接存在本地,但这样保存的图片不能直接使用,直接对比文件:
上图是正常的图片文件,下图是异常的图片文件,可以看出所有0a都转换成了0d 0a,当作文本格式自动将换行符转换成回车换行了;重新转换回来:
- file = open(tmp, 'rb')
- find = False
- for i in range(size):
- data = file.read(1)
- if data == '': break
- if find:
- if data != b'\n':
- w.write(b'\r')
- find = False
-
- if data == b'\r':
- find = True
- continue
- w.write(data)
运行发现转换后的图片不全,判断是截图指令还未执行完毕,判断临时文件长度没有变化才开始转换
- l = 0
- c = 0
- while True:
- size = os.path.getsize(tmp)
- if size != 0 and size == l: break
- l = size
- c += 1
- if c > 10: break
- time.sleep(0.2)
完整第二版代码:
- tmp = path_name('tmp',0)
- if device is None:
- cmd = f'adb shell screencap -p > {tmp}'
- else:
- cmd = f'adb -s {device} shell screencap -p > {tmp}'
- print(cmd,end='...')
- w = open(path, 'wb')
- ret = os.popen(cmd)
- time.sleep(1)
- l = 0
- c = 0
- while True:
- size = os.path.getsize(tmp)
- if size != 0 and size == l: break
- l = size
- c += 1
- if c > 10: break
- time.sleep(0.2)
- print(c,size)
- file = open(tmp, 'rb')
- find = False
- for i in range(size):
- data = file.read(1)
- if data == '': break
- if find:
- if data != b'\n':
- w.write(b'\r')
- find = False
-
- if data == b'\r':
- find = True
- continue
- w.write(data)
- w.close()
- file.close()
- print(path)
- #time.sleep(1)
- return path

相较第一版,速度有较大的提升,但感觉还是不太理想,图片数据临时保存到硬盘上,再读入处理,效率还是有点低,可否直接在内存中处理,去掉保存临时文件的步骤。尝试过直接读取popen管道数据,但是会报编码错误;在网上一通查找,找到subprocess.Popen方法;
第三版代码:
- cmd = []
- cmd.append('adb')
- device = sqlite.get_device()
- if not device is None:
- cmd.append('-s')
- cmd.append(device)
- cmd.append('shell')
- cmd.append('screencap')
- cmd.append('-p')
- print(cmd,end='...')
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
- #p.wait()
- output = p.communicate()[0]
- #print(output)
- size = len(output)
- print('size',size)
- #file = open(tmp, 'rb')
- w = open(path, 'wb')
- find = False
- c = 0
- for i in range(size):
- data = output[i].to_bytes(1,byteorder='little', signed=False) #file.read(1)
- if c < 10:
- print(data,end=' ')
- c += 1
- if data == '': break
- if find:
- if data != b'\n':
- w.write(b'\r')
- find = False
-
- if data == b'\r':
- find = True
- continue
- w.write(data)
- w.close()

感觉这个方法是最优的了,有两个地方需要注意:
output = p.communicate()[0]
p.communicate()返回的是数组,第一项才是输出;
data = output[i].to_bytes(1,byteorder='little', signed=False)
返回的是int类型数组,需要转换成byte
- if c < 10:
- print(data,end=' ')
打印了前10个字节,确定还是存在回车换行的问题,还是需要进行转换。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。