Android屏幕截图

来源:互联网 发布:python调用python脚本 编辑:程序博客网 时间:2024/06/18 09:12
我们在调屏时很多时候会出现花屏的现象,有的可能和屏有关系,有的时候可能和上层软件有关系,那么我们就要去确认了,到底是屏的问题,还是上层软件问题呢,我们可以通过截屏的方法来验证。

好在Android给我们提供了这样的工具screencap,那么首先来看命令help信息:
# screencap -husage: screencap [-hp] [-d display-id] [FILENAME]   -h: this message   -p: save the file as a png.   -d: specify the display id to capture, default 0.If FILENAME ends with .png it will be saved as a png.If FILENAME is not given, the results will be printed to stdout.

那么我们这里只需要-p选项就可以了,把图片保存到一个目录下,然后就可以把它拉出来查看了。
# screencap -p /sdcard/screenshot.png$ adb pull /sdcard/screenshot.png .

命令用法很简单的,很有用的一个工具。

除了screencap命令之外,还有个命令screenshot命令,这个命令主要是截取开机logo的命令,猜测是framebuffer并不只是一个缓冲区,有多个(两个),而其中的开机logo缓冲区并没有清掉,screenshot命令则就是截取该缓冲区的数据。

为此,我写了个screenshot.c程序,相当与screenshot命令,只是保存的图片为bmp格式,代码如下:

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <linux/fb.h>#include <sys/ioctl.h>#include <sys/mman.h>struct bitmap_fileheader {unsigned shorttype;unsigned intsize;unsigned shortreserved1;unsigned shortreserved2;unsigned intoff_bits;} __attribute__ ((packed));struct bitmap_infoheader {unsigned intsize;unsigned intwidth;unsigned intheight;unsigned shortplanes;unsigned shortbit_count;unsigned intcompression;unsigned intsize_image;unsigned intxpels_per_meter;unsigned intypels_per_meter;unsigned intclr_used;unsigned intclr_important;} __attribute__ ((packed));int saveimage(char *filename, char *fb, int width, int height, int bits_per_pixel){FILE *fp;struct bitmap_fileheader fh;struct bitmap_infoheader ih;int x, y;fp = fopen(filename, "wb");if (fp == NULL) {printf("can't open file %s\n", filename);return -1;}memset(&fh, 0, sizeof(struct bitmap_fileheader));fh.type= 0x4d42;fh.off_bits = sizeof(struct bitmap_fileheader) + sizeof(struct bitmap_infoheader);fh.size = fh.off_bits + width * height * (bits_per_pixel / 8);fwrite(&fh, 1, sizeof(struct bitmap_fileheader), fp);memset(&ih, 0, sizeof(struct bitmap_infoheader));ih.size = sizeof(struct bitmap_infoheader);ih.width = width;ih.height = height;ih.planes = 1;ih.bit_count = bits_per_pixel;/*ih.compression = 0;ih.size_image = 0;ih.xpels_per_meter = 0;ih.ypels_per_meter = 0;ih.clr_used = 0;ih.clr_important = 0;*/fwrite(&ih, 1, sizeof(struct bitmap_infoheader), fp);/*fwrite(fb, 1, width * height * (bits_per_pixel / 8), fp);*/fb += width * (bits_per_pixel / 8) * (height - 1);for (y = 0; y < height; y++, fb -= width * (bits_per_pixel / 8)) {fwrite(fb, 1, width * (bits_per_pixel / 8), fp);}fclose(fp);return 0;}int main(int argc, char *argv[]){int fd;struct fb_var_screeninfo var;char *fb;int size;fd = open("/dev/graphics/fb0", O_RDWR);if (fd < 0) {printf("can't open fb0!\n");return -1;}ioctl(fd, FBIOGET_VSCREENINFO, &var);printf("xres %d yres %d bpp %d\n", var.xres,var.yres, var.bits_per_pixel);size = var.xres * var.yres * (var.bits_per_pixel / 8);fb = (char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);saveimage(argv[1], fb, var.xres, var.yres, var.bits_per_pixel);munmap(fb, size);close(fd);return 0;}
注意该程序并没有考虑bmp图片4字节对齐问题,以及颜色反转问题。

我们还注意screencap命令有个-d选项,该选项默认参数为0,但不使用-d选项时,即参数为0时截取的就是屏当前显示的数据,当使用参数值大于等于1时,screencap命令就同screenshot命令一样,也是开机logo的数据。


// 2015.07.25 add

有的时候,可能只是截图不能满足一些场合,例如瞬时发生的闪屏现象,这个时候需要录像才能看清,好在android也提供了一个命令那就是screenrecord命令,可以通过screenrecord --help查看其具体用法,这里只给出一个简单的用法,例如:

screenrecord /sdcard/demo.mp4

0 0
原创粉丝点击