本文来自网易云社区

作者:孙圣翔

在一张Android手机上截图有好多办法,为了能够高效率的截图,我几乎把所有的方法都尝试了一般。走了好多路,也遇到了好多的问题。

只是想记录下这其中的不容易。

下面所有的测试都是用的我的三星 S4.

屏幕分辨率 1080x1920

androidviewclient

截图速度: 4.5s

最开始截图用的是 google官方提供的纯python库androidviewclient,代码的地址在 github.com/dtmilano/An…

基于adb协议,只能在电脑上用。最初被我用在的一个手游自动化测试工具airtest上面。使用它很简单,我写个简单的例子from com.dtmilano.android.viewclient import ViewClient

c, _ = ViewClient.connectToDeviceOrExit(verbose=False, serialno='10.242.74.241:5555')

s = c.takeSnapshot()

s.save('snapshot.png', 'PNG')复制代码

不过这个python库也有坑人的地方。它更新到pypi的时候,所有的历史版本都找不到。使得可以更新过去,但是更新不回来。

最新的版本在有些机器上还跑不了。截图的时候某些手机还会出现图片缺少颜色的问题。

screencap

截图速度: 2.0s

Android手机上自带有一个截图工具,一般都是被放在了/system/bin/screencap下。

使用的时候需要在电脑上安装adb,然后adb shell进入shell环境,使用的时候,需要生成一个临时图片在手机上,然后把照片从手机上传输回来。

可以写成一个批处理脚本@echo off

adb shell screencap -p /sdcard/snapshot.png

adb pull /sdcard/snapshot.png

adb shell rm /sdcard/snapshot.png复制代码

这个样子截图,要比androidviewclient的稳定性好很多。只是需要生成一个临时文件,感觉好别扭。

APK程序直接截图

截图速度: < 1s

stackoverflow上也有不少代码例子。apk必须用java写,意味着我必须学一下java了,买了一本书《Android第一行代码》。

学习了2个多星期,总算入门了。然后写了一个手机app截图。截图代码我就不贴了,这个比较长一点,网上也有很多例子。

这种方法截图效率在1s以内。不过只有在当前App在前台运行的时候才可以截图。就算写成Service也不行。

后来想想,截取不到图也算合理。假如一个App可以截取到其他App运行时的图片,岂不是越权了,用户的隐私还怎么保证。

既然这样,只能放弃了。

ASL

之后有幸看到了google出的一个android-screenshot-library的东西,简称ASL。代码在code.google.com/p/android-s…

看到这个东西真是让人欣喜若狂。立马下载下来试了试,心情立马就不好了,截图来的图,竟然是黑屏。接着又借了4个手机试验。

结果截图只有一台手机截出来的图能看(还是缺少一个颜色通道的那种)。 看看了代码实现的原理,是直接读取framebuffer。

这个地方我解释下:

在linux中,所有的东西通通都可以映射成文件,连屏幕映射成了文件。android的在/dev/graphics/fb0。

通过读取fb0中的数据,然后在根据一些算法就可以还原出屏幕的图像了。

还有一个库, code.google.com/p/android-f… 看代码原理应该和ASL差不多,不过实现了PC端的一个adb_screenshot的程序。

没法截图怎么用啊,放弃吧。 哎

重回screencap, Golang重写截图程序。

截图速度: 1s

好在android是开源的,直接可以翻到screencap实现的源码。意外的发现他有两种输出格式。

一种是png格式 (耗时1.5s)

还有一种是原始的图片格式(这种原始的格式,跟bmp差不多)。 试验了下,好使400ms

之前看过一个韩国人写的remotedroid 截图速度快的让人震惊。

所以我在想是不是screencap中png的压缩算法有问题。参考下代码中,他输出的格式。用Go语言写了一个转化的程序。// TakeSnapshot by cmd: /system/bin/screencap

func TakeSnapshot() (img *image.RGBA, err error) {

scrbf = bytes.NewBuffer(nil)

cmd := exec.Command("screencap")

cmd.Stdout = scrbf

if err = cmd.Run(); err != nil {

return

}

var width, height, format int32

binary.Read(scrbf, binary.LittleEndian, &width)

binary.Read(scrbf, binary.LittleEndian, &height)

err = binary.Read(scrbf, binary.LittleEndian, &format)

if err != nil {

return

}

img = image.NewRGBA(image.Rectangle{image.ZP, image.Point{int(width), int(height)}})

return

}

func main(){

s, _ := TakeSnapshot()

out, _ := os.Create("snapshot.png")

defer out.Close()

png.Encode(out, s)

}复制代码

利用总共用时1.2s的样子。比之前用screencap 2s快了不少哎。感觉似乎还可以更快点。把png改成jpeg试试。func main(){

s, _ := TakeSnapshot()

out, _ := os.Create("snapshot.png")

defer out.Close()

jpeg.Encode(out, s, jpeg.Options{60})

}复制代码

这种方法变成了1.1s, 感觉似乎还可以更快点。 需要稍微复杂点,需要减少内存申请和拷贝的次数。// TakeSnapshot by cmd: /system/bin/screencap

var SCRBUFLEN int

func TakeSnapshot() (img *image.RGBA, err error) {

var scrbf *bytes.Buffer

if SCRBUFLEN == 0 {

scrbf = bytes.NewBuffer(nil)

} else {

scrbf = bytes.NewBuffer(make([]byte, 0, SCRBUFLEN))

}

cmd := exec.Command("screencap")

cmd.Stdout = scrbf

if err = cmd.Run(); err != nil {

return

}

var width, height, format int32

binary.Read(scrbf, binary.LittleEndian, &width)

binary.Read(scrbf, binary.LittleEndian, &height)

SCRBUFLEN = int(width * height * 4

err = binary.Read(scrbf, binary.LittleEndian, &format)

if err != nil {

return

}

w, h := int(width), int(height)

img = &image.RGBA{scrbf.Bytes(), 4 * w, image.Rect(0, 0, w, h)}

return

}复制代码

改完后,变成1.0s了。 终于到了还算可以接受的程度。 整理下代码终于可以让他抛头露面了。

这就是我在做Android截图的时候,所遇到的大部分问题。要知道截个图是多么的不容易。 另外想说,请一定不要放弃,总会有办法的。

网易云免费体验馆,0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区。

android截图工具效率,Android之高效率截图相关推荐

  1. 全网最全Android开发工具,Android开发框架大全

    涵盖Android方方面面的技术, 目前保持更新. 时刻与Android开发流行前沿同步. 目录 一.工具 Android开发工具 在线工具宝典大全 二.框架 *缓存框架* DiskLruCache ...

  2. Android开发工具视频Android 12(S)准备

    Android开发工具视频Android 12(S)准备 适配步骤 下载最新的Android studio工具,点我到官网下载最新的吧! 最新版的studio规定jdk使用必须至少11,所以请移步下载 ...

  3. Android 开发工具集合 - (Android Dev Tools)

    收集整理Android开发所需的Android SDK.开发中用到的工具.Android开发教程.Android设计规范,免费的设计素材等. 欢迎大家推荐自己在Android开发过程中用的好用的工具. ...

  4. android aidl工具,【Android】AIDL介绍和实例讲解

    前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Process Communication,进程间通信)的一种独特实现: AIDL (Android Interface ...

  5. 【Tool】一款轻量级的强大截图工具--Sinpaste | 从此告别QQ截图

    文章目录 sinpaste介绍 sinpast基础操作 切换中文模式 快捷操作 截图 何谓一次 成功的截图 取消当前截图 回放截图记录 逐像素控制光标移动 像素级控制截取区域 放大镜 取色 标注 手动 ...

  6. Android开发工具之Android Studio----Gradle

    .gradle 文件介绍 一个 Android Studio 项目中,会存在多个 .gradle 文件.其中, project 目录下存在一个 build.gradle 文件和一个 settings. ...

  7. android sharedpreferences 工具类,android sharedpreferences工具类

    释放双眼,带上耳机,听听看~! 今天,简单讲讲如何写一个sharedpreferences的工具类. 很简单,把一些重复的操作封装在工具类里,其他地方调用就可以.在网上搜索了比较多的资料,找到一个比较 ...

  8. C#关于制作截图工具(一)简单截图

    记得我以前开始想做截图工具的时候 在网上看了n多 虽然网上有很多这类文章 不过当时我感觉我看的那些文章对于我来说"太华丽"了有点 因为网上看的那些都是做的一整个截图工具上面包含了很 ...

  9. 【Tools】macOS 截图工具推荐xnip(滚动截图截长图、步骤截图)

    20181113截图工具先用了腾讯的snip,滚动截图我在chrome和别的软件下测试下没成功.而且需要修改辅助功能. xnip实现的原理似乎是鼠标滚动时软件自己拼接图片. 此外,xnip的步骤截屏非 ...

最新文章

  1. servlet response 中文乱码
  2. 一般将来时语法课教案_「英语语法」一般过去时用法技巧全解
  3. RubyMine 2018.3.5 发布,流行的 Ruby 开发工具
  4. 解救人质的android游戏,黑帽子解救人质全关卡解锁版 1.03 安卓版
  5. Java 中抽象类与接口
  6. 监听手指是否离开屏幕android_Flutter事件监听
  7. 爬虫-请求图片并打开显示图片
  8. yosemite php gd,Yosemite下配置PHP支持GD库FreeType
  9. 02 java多线程基础
  10. PathAnimation
  11. 微信小程序----实现YDUI的ScrollTab(滚动选项卡)
  12. windows2008服务器安全防护软件哪个好
  13. 【项目管理/PMP/PMBOK第六版/新考纲】纯干货!商业论证/效益管理计划/项目运行环境/组织过程资产/环境事业因素/组织系统,系列笔记建议收藏!
  14. Exception in thread “main“ java.lang.NumberFormatException
  15. linux:挂载、rpm、yum、scp、ssh、crontab、时钟同步
  16. 前后落差大用什么词语_形容前后反差大的词语
  17. 关于前端在vue中实现‘距离某个时间点的倒计时’问题:设置了间隔计算时间,刚开始有停顿。
  18. 220V交流电向单片机供电电路设计思路
  19. 出口欧盟万圣节cosplay服装CE认证办理标准
  20. 运动App如何实现端侧后台保活,让运动记录更完整?

热门文章

  1. JS常用的数组方法和循环
  2. 四档开启!windows7系统下载全新体验来袭!
  3. 不想做灯罩的荷叶不是好猫窝,我把这个送你,你让我吸吸好吗?丨钛空舱
  4. Android 朋友圈 输入框评论效果
  5. vue引入css三种方式
  6. 手游神武2最新服务器,《神武》再开新服 预告搭配豪礼相送
  7. 京东金融网银钱包移动版上线 将接入外部商户
  8. 深入理解GBDT二分类算法
  9. python中标准的六个数据类型详解
  10. 前端全栈学习第十二天-js第三天-基础