linux framebuff 其实是本身linux写缓存的一种机制,对于应用级别的程序,比如需要获取屏幕的尺寸等等,只需要拥有足够的权限,打开相应的设备,然后再使用ioctl 接口获取相应的信息,然后再通过mmap获取相应的地址,然后进行相应的操作即可,咳,我的第一篇写的博客,没有保存,结果给弄丢了,现在一下子没有心情写了,随便写点吧郁闷


基本上开发步骤如下:

1、判断出你使用的设备
2、打开设备
3、取回或改变屏幕设置
4、映射(Map)屏幕内存
通常要打开的设备是/dev/fb0,但是如果用户有多个视频卡和监视器的话,设备也可能不同。大多数应用通过读取环境变量FRAMEBUFFER (用getenv();)来决定该使用哪个设备。如果该环境变量不存在,那么就用/dev/fb0。
通过open()调用打开设备,读设备意味着读取屏幕内存(可称之为显存)。用$cat /dev/fb0 >screenshot将屏幕内存导入一个文件,恢复刚才的屏幕截图则可使用:$cat screenshot >/dev/fb0。


然后百度百科上搜索相关的信息

Framebuffer Driver 这个关键字在百度上一搜索就可以了,里面讲解很详细,也很好理解



关于ioctl支持的有如下的

#define FBIOGET_VSCREENINFO 0x4600
#define FBIOPUT_VSCREENINFO 0x4601
#define FBIOGET_FSCREENINFO 0x4602
#define FBIOGETCMAP 0x4604
#define FBIOPUTCMAP 0x4605
#define FBIOPAN_DISPLAY 0x4606
#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor)
/* 0x4607-0x460B are defined below */
/* #define FBIOGET_MONITORSPEC 0x460C */
/* #define FBIOPUT_MONITORSPEC 0x460D */
/* #define FBIOSWITCH_MONIBIT 0x460E */
#define FBIOGET_CON2FBMAP 0x460F
#define FBIOPUT_CON2FBMAP 0x4610
#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */
#define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank)
#define FBIO_ALLOC 0x4613
#define FBIO_FREE 0x4614
#define FBIOGET_GLYPH 0x4615
#define FBIOGET_HWCINFO 0x4616
#define FBIOPUT_MODEINFO 0x4617
#define FBIOGET_DISPINFO 0x4618
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)


关键的几个有如下

1 FBIOGET_FSCREENINFO 返回与Framebuffer有关的固定的信息,比如图形硬件上实际的帧缓存空间的大小、能否硬件加速等信息。

对应结构体

struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */ID
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; /* Interleave for interleaved Planes */插入区域?
__u32 visual; /* see FB_VISUAL_* */
__u16 xpanstep; /* zero if no hardware panning */没有硬件设备就为零
__u16 ypanstep; /* zero if no hardware panning */
__u16 ywrapstep; /* zero if no hardware ywrap */
__u32 line_length; /* length of a line in bytes */ 一行的字节表示
unsigned long mmio_start; /* Start of Memory Mapped I/O */内存映射的I/O起始
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */ I/O的大小
__u32 accel; /* Type of acceleration available */ 可用的加速类型
__u16 reserved[3]; /* Reserved for future compatibility */
};



2 FBIOGET_VSCREENINFO 返回的是与Framebuffer有关的可变信息。

对应结构体

struct fb_var_screeninfo
{
__u32 xres; /* visible resolution */ //可视区域
__u32 yres;
__u32 xres_virtual; /* virtual resolution */ //可视区域
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible resolution */ //可视区域的偏移
__u32 yoffset;
__u32 bits_per_pixel; /* guess what */ //每一象素的bit数
__u32 grayscale; /* != 0 Gray levels instead of colors *///等于零就成黑白
struct fb_ bitfield red; /* bitfield in fb mem if true color, */真彩的bit机构
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */ 透明
__u32 nonstd; /* != 0 Non standard pixel format */ 不是标准格式
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */ 内存中的图像高度
__u32 width; /* width of picture in mm */ 内存中的图像宽度
__u32 accel_flags; /* acceleration flags (hints) */ 加速标志
/* Timing: All values in pixclocks, except pixclock (of course) */
时序-_-这些部分就是显示器的显示方法了,可以找相关的资料看看
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */ 水平可视区域
__u32 vsync_len; /* length of vertical sync */ 垂直可视区域
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 reserved[6]; /* Reserved for future compatibility */ 备用-以后开发
};


3 FBIOPUT_VSCREENINFO 这个应该是写入,设置屏幕分别率什么的,不过暂时没有编程试验过


4 linux屏幕截图

下面有个例子写的不错

http://www.cnblogs.com/lknlfy/archive/2012/04/18/2455961.html


可以来进行参考一下。

不过android平台的 screenshot 这个文件做法和上面的例子还不太一样