Android之高效率截图

栏目: IOS · Android · 发布时间: 6年前

内容简介:本文来自网易云社区作者:孙圣翔在一张Android手机上截图有好多办法,为了能够高效率的截图,我几乎把所有的方法都尝试了一般。走了好多路,也遇到了好多的问题。

本文来自网易云社区

作者:孙圣翔

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

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

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

屏幕分辨率 1080x1920

androidviewclient

截图速度: 4.5s

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

基于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。代码在 http://code.google.com/p/android-screenshot-library/

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

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

这个地方我解释下:

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

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

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

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

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

截图速度: 1s

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

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

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

之前看过一个韩国人写的remotedroid < https://code.google.com/p/remoteroid/ > 截图速度快的让人震惊。

所以我在想是不是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了。 终于到了还算可以接受的程度。 整理下代码终于可以让他抛头露面了。

https://github.com/netease/airinput

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

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

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

相关文章:

【推荐】  为何要在网站上设置的验证码

【推荐】  如何准确又通俗易懂地解释大数据及其应用价值?


以上所述就是小编给大家介绍的《Android之高效率截图》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高性能JavaScript

高性能JavaScript

【美】Nicholas C. Zakas(尼古拉斯.泽卡斯) / 丁琛 / 电子工业出版社 / 2015-8-1 / 65

如果你使用 JavaScript 构建交互丰富的 Web 应用,那么 JavaScript 代码可能是造成你的Web应用速度变慢的主要原因。《高性能JavaScript》揭示的技术和策略能帮助你在开发过程中消除性能瓶颈。你将会了解如何提升各方面的性能,包括代码的加载、运行、DOM 交互、页面生存周期等。雅虎的前端工程师 Nicholas C. Zakas 和其他五位 JavaScript 专家介绍......一起来看看 《高性能JavaScript》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具