From e01d623e982ab543b8c8ccc7eccd96e5d2924559 Mon Sep 17 00:00:00 2001 From: hongbochen Date: Wed, 21 Oct 2015 10:26:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E8=BF=99=E9=87=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86=E4=B8=8A=E4=B8=80=E4=B8=AA=E5=B0=8F=E8=8A=82=E4=B8=AD?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=AE=9E=E7=8E=B0=E7=9A=84p=5Frgbt=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fb3/README.md | 118 ++++++++++++++++++++++++++++++++++++++++++++ fb3/fbtool.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ fb3/fbtool.c~ | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ fb3/fbtool.h | 41 ++++++++++++++++ fb3/fbtool.h~ | 41 ++++++++++++++++ fb3/test | Bin 0 -> 13322 bytes fb3/test.c | 37 ++++++++++++++ fb3/test.c~ | 38 +++++++++++++++ 8 files changed, 541 insertions(+) create mode 100644 fb3/README.md create mode 100644 fb3/fbtool.c create mode 100644 fb3/fbtool.c~ create mode 100644 fb3/fbtool.h create mode 100644 fb3/fbtool.h~ create mode 100755 fb3/test create mode 100644 fb3/test.c create mode 100644 fb3/test.c~ diff --git a/fb3/README.md b/fb3/README.md new file mode 100644 index 0000000..2fd47b0 --- /dev/null +++ b/fb3/README.md @@ -0,0 +1,118 @@ +**(一):写在前面** + +在这个小节中,主要介绍了frame buffer中的R,G,B以及透明度的位域属性.由于在上一个小节当中,我自私的以为这几个位域能够获得相应的R,G,B以及透明度的数值,然后再将其转化为图像,但是,经过我后来的学习,发现我错了.正确的将frame buffer读取并转换为图像的方法是首先读取(read)frame buffer,然后,再将读取的char数组转换为相应的图片.所以,后面,着重学习如何读取frame buffer,以及如何将其转化为图片. + +**(二):R,G,B以及透明度位域** + +在fb.h头文件中的结构 fb_var_screeninfo中定义了R,G,B以及透明度的位域,他们都是一个结构体fb_bitfield的一个实例.下面我们来看一下bitfield的定义: + +``` +struct fb_bitfield { + __u32 offset; /* 位域的开始 */ + __u32 length; /* length of bitfield 位域的长度 */ + __u32 msb_right; /* != 0 : Most significant bit is right 不等于0,大多数重要的位是右边的 */ +}; +``` + +那么如果要打印该值的话,我们就需要使用该结构体. + +**(三):完善上一节中的p_rgbt(PFBDEV pFbdev)函数** + +在我们的上一节中,我们留下了这个函数而没有去实现,这个来源于我的无知.所以,现在我们来完善一下这个函数.在上面我们知道这个关系之后,这个函数的实现就显得相对简单了. + +``` +//打印R,G,B和透明度 +void p_rgbt(PFBDEV pFbdev) +{ + //R位域 + printf("R位域:\n"); + struct fb_bitfield bf = pFbdev->fb_var.red; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + //G位域 + printf("G位域:\n"); + bf = pFbdev->fb_var.green; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + // B位域 + printf("B位域:\n"); + bf = pFbdev->fb_var.blue; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + // 透明度位域 + printf("透明度位域:\n"); + bf = pFbdev->fb_var.transp; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); +} +``` + +**(四):编译运行方法** + +编译和运行方法和上一节的编译运行方法是一样的. + +**(五):运行结果展示** + +下面我们来看一下我们的运行结果: + +``` +frame buffer所占内存的开始地址为:-1341710336 +frame buffer 的类型为:0 +frame buffer的可见清晰度为: + x = 1366 + y = 768 +frame buffer的虚拟清晰度为: + x = 1366 + y = 768 +frame buffer的虚拟分辨率到可见分辨率的偏移量为: + x = 0 + y = 0 +frame buffer的BPP为:32 +R位域: + 开始:16 + 长度:8 + MSB:0 +G位域: + 开始:8 + 长度:8 + MSB:0 +B位域: + 开始:0 + 长度:8 + MSB:0 +透明度位域: + 开始:0 + 长度:0 + MSB:0 +frame buffer在内存中所占的高度和宽度分别是: + 宽度 = -1 + 高度 = -1 +R位域: + 开始:16 + 长度:8 + MSB:0 +G位域: + 开始:8 + 长度:8 + MSB:0 +B位域: + 开始:0 + 长度:8 + MSB:0 +透明度位域: + 开始:0 + 长度:0 + MSB:0 + +``` + +**(六):写在后面** + +今天很残酷,明天很残酷,后天很没有,但是绝大多数人死在了明天晚上.----马云 \ No newline at end of file diff --git a/fb3/fbtool.c b/fb3/fbtool.c new file mode 100644 index 0000000..03d6742 --- /dev/null +++ b/fb3/fbtool.c @@ -0,0 +1,133 @@ +#include "fbtool.h" + +//打开并且初始化该frame buffer +int fb_open(PFBDEV pFbdev) +{ + //打开frame buffer + pFbdev->fb = open(pFbdev->dev,O_RDWR); + + if(pFbdev->fb < 0) + { + printf("打开错误 %s : %n.请检查内核配置\n",pFbdev->dev); + return 0; + } + + // 初始化fb_var + if(-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var))) + { + printf("ioctl FBIOGET_VSCREENINFO\n"); + return 0; + } + + // 初始化fb_fix + if(-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix))) + { + printf("ioctl FBIOGET_FSCREENINFO\n"); + return 0; + } + + return 1; +} + +//关闭frame buffer +int fb_close(PFBDEV pFbdev) +{ + close(pFbdev->fb); + pFbdev->fb = -1; +} + +//打印frame buffer 所占内存的开始地址  +void pmem_start(PFBDEV pFbdev) +{ + printf("frame buffer所占内存的开始地址为:%d\n",pFbdev->fb_fix.smem_start); +} + +//打印FB_TYPE +void p_type(PFBDEV pFbdev) +{ + printf("frame buffer 的类型为:%d\n",pFbdev->fb_fix.type); +} + +//打印可见清晰度 +void p_visible_res(PFBDEV pFbdev) +{ + printf("frame buffer的可见清晰度为:\n\tx = %d\n\ty = %d\n",pFbdev->fb_var.xres,pFbdev->fb_var.yres); +} + +//打印虚拟分辨率 +void p_virt_res(PFBDEV pFbdev) +{ + printf("frame buffer的虚拟清晰度为:\n\tx = %d\n\ty = %d\n",pFbdev->fb_var.xres_virtual,pFbdev->fb_var.yres_virtual); +} + +//打印虚拟到可见的偏移量 +void p_offset(PFBDEV pFbdev) +{ + printf("frame buffer的虚拟分辨率到可见分辨率的偏移量为:\n\tx = %d\n\ty = %d\n",pFbdev->fb_var.xoffset,pFbdev->fb_var.yoffset); +} + +//打印每个像素的位数 +void p_bpp(PFBDEV pFbdev) +{ + printf("frame buffer的BPP为:%d\n",pFbdev->fb_var.bits_per_pixel); +} + +//打印R,G,B和透明度 +void p_rgbt(PFBDEV pFbdev) +{ + //R位域 + printf("R位域:\n"); + struct fb_bitfield bf = pFbdev->fb_var.red; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + //G位域 + printf("G位域:\n"); + bf = pFbdev->fb_var.green; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + // B位域 + printf("B位域:\n"); + bf = pFbdev->fb_var.blue; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + // 透明度位域 + printf("透明度位域:\n"); + bf = pFbdev->fb_var.transp; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); +} + +//打印在内存中的高度和宽度 +void p_hw(PFBDEV pFbdev) +{ + printf("frame buffer在内存中所占的高度和宽度分别是:\n\t宽度 = %d\n\t高度 = %d\n",pFbdev->fb_var.height,pFbdev->fb_var.width); +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/fb3/fbtool.c~ b/fb3/fbtool.c~ new file mode 100644 index 0000000..03d6742 --- /dev/null +++ b/fb3/fbtool.c~ @@ -0,0 +1,133 @@ +#include "fbtool.h" + +//打开并且初始化该frame buffer +int fb_open(PFBDEV pFbdev) +{ + //打开frame buffer + pFbdev->fb = open(pFbdev->dev,O_RDWR); + + if(pFbdev->fb < 0) + { + printf("打开错误 %s : %n.请检查内核配置\n",pFbdev->dev); + return 0; + } + + // 初始化fb_var + if(-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var))) + { + printf("ioctl FBIOGET_VSCREENINFO\n"); + return 0; + } + + // 初始化fb_fix + if(-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix))) + { + printf("ioctl FBIOGET_FSCREENINFO\n"); + return 0; + } + + return 1; +} + +//关闭frame buffer +int fb_close(PFBDEV pFbdev) +{ + close(pFbdev->fb); + pFbdev->fb = -1; +} + +//打印frame buffer 所占内存的开始地址  +void pmem_start(PFBDEV pFbdev) +{ + printf("frame buffer所占内存的开始地址为:%d\n",pFbdev->fb_fix.smem_start); +} + +//打印FB_TYPE +void p_type(PFBDEV pFbdev) +{ + printf("frame buffer 的类型为:%d\n",pFbdev->fb_fix.type); +} + +//打印可见清晰度 +void p_visible_res(PFBDEV pFbdev) +{ + printf("frame buffer的可见清晰度为:\n\tx = %d\n\ty = %d\n",pFbdev->fb_var.xres,pFbdev->fb_var.yres); +} + +//打印虚拟分辨率 +void p_virt_res(PFBDEV pFbdev) +{ + printf("frame buffer的虚拟清晰度为:\n\tx = %d\n\ty = %d\n",pFbdev->fb_var.xres_virtual,pFbdev->fb_var.yres_virtual); +} + +//打印虚拟到可见的偏移量 +void p_offset(PFBDEV pFbdev) +{ + printf("frame buffer的虚拟分辨率到可见分辨率的偏移量为:\n\tx = %d\n\ty = %d\n",pFbdev->fb_var.xoffset,pFbdev->fb_var.yoffset); +} + +//打印每个像素的位数 +void p_bpp(PFBDEV pFbdev) +{ + printf("frame buffer的BPP为:%d\n",pFbdev->fb_var.bits_per_pixel); +} + +//打印R,G,B和透明度 +void p_rgbt(PFBDEV pFbdev) +{ + //R位域 + printf("R位域:\n"); + struct fb_bitfield bf = pFbdev->fb_var.red; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + //G位域 + printf("G位域:\n"); + bf = pFbdev->fb_var.green; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + // B位域 + printf("B位域:\n"); + bf = pFbdev->fb_var.blue; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); + + // 透明度位域 + printf("透明度位域:\n"); + bf = pFbdev->fb_var.transp; + printf("\t开始:%d\n",bf.offset); + printf("\t长度:%d\n",bf.length); + printf("\tMSB:%d\n",bf.msb_right); +} + +//打印在内存中的高度和宽度 +void p_hw(PFBDEV pFbdev) +{ + printf("frame buffer在内存中所占的高度和宽度分别是:\n\t宽度 = %d\n\t高度 = %d\n",pFbdev->fb_var.height,pFbdev->fb_var.width); +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/fb3/fbtool.h b/fb3/fbtool.h new file mode 100644 index 0000000..a919b5e --- /dev/null +++ b/fb3/fbtool.h @@ -0,0 +1,41 @@ +#ifndef __FBTOOL_H_ +#define __FBTOOL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct fbdev{ + int fb; //framebuffer打开后的唯一标识符 + struct fb_fix_screeninfo fb_fix; + struct fb_var_screeninfo fb_var; + char dev[20]; +}FBDEV,*PFBDEV; + +//打开framebuffer +int fb_open(PFBDEV pFbdev); +//关闭framebuffer +int fb_close(PFBDEV pFbdev); +//打印frame buffer 所占内存的开始地址  +void pmem_start(PFBDEV pFbdev); +//打印FB_TYPE +void p_type(PFBDEV pFbdev); +//打印可见清晰度 +void p_visible_res(PFBDEV pFbdev); +//打印虚拟分辨率 +void p_virt_res(PFBDEV pFbdev); +//打印虚拟到可见的偏移量 +void p_offset(PFBDEV pFbdev); +//打印每个像素的位数 +void p_bpp(PFBDEV pFbdev); +//打印R,G,B和透明度 +void p_rgbt(PFBDEV pFbdev); +//打印在内存中的高度和宽度 +void p_hw(PFBDEV pFbdev); + +#endif diff --git a/fb3/fbtool.h~ b/fb3/fbtool.h~ new file mode 100644 index 0000000..a919b5e --- /dev/null +++ b/fb3/fbtool.h~ @@ -0,0 +1,41 @@ +#ifndef __FBTOOL_H_ +#define __FBTOOL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct fbdev{ + int fb; //framebuffer打开后的唯一标识符 + struct fb_fix_screeninfo fb_fix; + struct fb_var_screeninfo fb_var; + char dev[20]; +}FBDEV,*PFBDEV; + +//打开framebuffer +int fb_open(PFBDEV pFbdev); +//关闭framebuffer +int fb_close(PFBDEV pFbdev); +//打印frame buffer 所占内存的开始地址  +void pmem_start(PFBDEV pFbdev); +//打印FB_TYPE +void p_type(PFBDEV pFbdev); +//打印可见清晰度 +void p_visible_res(PFBDEV pFbdev); +//打印虚拟分辨率 +void p_virt_res(PFBDEV pFbdev); +//打印虚拟到可见的偏移量 +void p_offset(PFBDEV pFbdev); +//打印每个像素的位数 +void p_bpp(PFBDEV pFbdev); +//打印R,G,B和透明度 +void p_rgbt(PFBDEV pFbdev); +//打印在内存中的高度和宽度 +void p_hw(PFBDEV pFbdev); + +#endif diff --git a/fb3/test b/fb3/test new file mode 100755 index 0000000000000000000000000000000000000000..23e88e528c845499924fa3d03921bb70d8750a58 GIT binary patch literal 13322 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