Android平台截图研究 FrameBuffer(/dev/graphics/fb0) 文件内容研究!(含源码工程)


1. FrameBuffer文件介绍


FrameBuffer 文件是 Linux (Android是基于Linux的) 对显示设备的一种抽象设备,相当于显存。Android 的 SurfaceFlinger 想更新屏幕的时候,就会把相应的改变写入到FrameBuffer里。Android 2.x 的时代,显示开机画面的功能也是通过把图像数据写入到FrameBuffer实现的。所以,你可以认为,FrameBuffer里头一定有当前屏幕内容的图像数据。

Android平台上,FrameBuffer 文件的绝对路径一般是: /dev/graphics/fb0 。

所以,如果我们想截图,其中一种方法就是把FrameBuffer里头的图像数据取出来,转换成bitmap,然后存储起来或者给ImageView来显示出来。

2. FrameBuffer文件格式


现在我们知道 FrameBuffer (/dev/graphics/fb0) 文件里头会有当前屏幕的图像数据,取出来就可以了。但是,如果你直接运行这段代码:
		public void test() {
			byte[] fb_data = new byte[5000000];
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(new File("/dev/graphics/fb0"));
				DataInputStream dStream = new DataInputStream(fis);
				dStream.readFully(fb_data);
				dStream.close();
				
				Bitmap bm = BitmapFactory.decodeByteArray(fb_data, 0, fb_data.length);
				mImageView.setBackground(new BitmapDrawable(bm));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
会遇到两个问题:
1. /dev/graphics/fb0 文件会拒绝访问,所以你要让你的程序获取root权限后,才能取到/dev/graphics/fb0里头的数据 ,或者获取 root 权限后把 /dev/graphics/fb0 文件改为所有用户可读 (如何获取root权限,这篇文章暂不讨论)
2. 取到数据后,decode成bitmap,让imageview显示,会花屏,或者索性什么都没显示。

花屏或者什么都不显示,那是因为 FrameBuffer 里头的数据并不是常见的图像数据,直接丢给 BitmapFactory 显示,BitmapFactory 也不知道你这一堆什么玩意儿,所以出来的图像要么花屏,要么什么都不显示。

那我们现在进入正题:FrameBuffer 里头的数据到底是怎么样的?

要弄清这个问题,我们需要在我们的jni代码里执行这段代码:

int fd, ret;
struct fb_fix_screeninfo finfo;


// 打开Framebuffer设备
fd = open("/dev/graphics/fb0", O_RDONLY);


if(fd < 0)
{
<span style="white-space:pre">	</span>LOGD("======Cannot open /dev/graphics/fb0!");
<span style="white-space:pre">	</span>return -1;
}


// 获取Framebuffer 的 fixed info 不变信息
ret = ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
if(ret < 0 )
{
<span style="white-space:pre">	</span>LOGD("Cannot get fixed screen information.");
<span style="white-space:pre">	</span>close(fd);
<span style="white-space:pre">	</span>return -1;
}

 通过这段代码,我们获取到了 Framebuffer 设备的 “不变信息” :其实就是一个名叫 fb_fix_screeninfo 的结构体,这个结构体里包含了我们的 Framebuffer 数据的格式。 
 
fb_fix_screeninfo这个结构体定义在 linux/include/linux/fb.h 头 文件里头 ( 虽然这个头文件是linux源码里头找的,但是 fb.h 里头定义的很多东西,Android 都直接沿用了)
定义如下:
 struct fb_fix_screeninfo {
         char id[16];                    /* identification string eg "TT Builtin" */
         unsigned long smem_start;       /* Start of frame buffer mem */
                                         /* (physical address) */
         __u32 smem_len;                 /* Length of frame buffer mem */
         __u32 type;                     /* see FB_TYPE_*                */
         __u32 type_aux;                 
  • 3
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值