本文转载自:http://blog.csdn.net/luxiaoxun/article/details/7622988

framebuffer简介

帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。framebuffer是LCD对应的一中HAL(硬件抽象层),提供抽象的,统一的接口操作,用户不必关心硬件层是怎么实施的。这些都是由Framebuffer设备驱动来完成的。 
    帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux下还可支持多个帧缓冲设备,最多可达32个,分别为/dev/fb0到 /dev/fb31,而/dev/fb则为当前缺省的帧缓冲设备,通常指向/dev/fb0,在嵌入式系统中支持一个显示设备就够了。帧缓冲设备为标准字符设备,主设备号为29,次设备号则从0到31。分别对应/dev/fb0-/dev/fb31。

通过/dev/fb,应用程序的操作主要有这几种: 
1. 读/写(read/write)/dev/fb:相当于读/写屏幕缓冲区。 
2. 映射(map)操作:由于Linux工作在保护模式,每个应用程序都有自己的虚拟地址空间,在应用程序中是不能直接访问物理缓冲区地址的。而帧缓冲设备可以通过mmap()映射操作将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址上,然后用户就可以通过读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图了。 
3. I/O控制:对于帧缓冲设备,对设备文件的ioctl操作可读取/设置显示设备及屏幕的参数,如分辨率,屏幕大小等相关参数。ioctl的操作是由底层的驱动程序来完成的。

在应用程序中,操作/dev/fb的一般步骤如下: 
1. 打开/dev/fb设备文件。 
2. 用ioctl操作取得当前显示屏幕的参数,根据屏幕参数可计算屏幕缓冲区的大小。 
3. 将屏幕缓冲区映射到用户空间。 
4. 映射后即可直接读写屏幕缓冲区,进行绘图和图片显示。

framebuffer相关数据结构介绍 
1. fb_info结构体:帧缓冲设备中最重要的数据结构体,包括了帧缓冲设备属性和操作的完整性属性。
2. fb_ops结构体:fb_info结构体的成员变量,fb_ops为指向底层操作的函数的指针。
3.fb_var_screen和fb_fix_screen结构体:fb_var_screen记录用户可以修改的显示控制器参数,fb_fix_screen记录用户不能修改的显示控制器参数。

以下代码使用framebuffer显示一张图片:

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <string.h>
  6. #include <linux/fb.h>
  7. #include <sys/mman.h>
  8. #include <sys/ioctl.h>
  9. #include <arpa/inet.h>
  10. //14byte文件头
  11. typedef struct
  12. {
  13. char cfType[2];//文件类型,"BM"(0x4D42)
  14. long cfSize;//文件大小(字节)
  15. long cfReserved;//保留,值为0
  16. long cfoffBits;//数据区相对于文件头的偏移量(字节)
  17. }__attribute__((packed)) BITMAPFILEHEADER;
  18. //__attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐
  19. //40byte信息头
  20. typedef struct
  21. {
  22. char ciSize[4];//BITMAPFILEHEADER所占的字节数
  23. long ciWidth;//宽度
  24. long ciHeight;//高度
  25. char ciPlanes[2];//目标设备的位平面数,值为1
  26. int ciBitCount;//每个像素的位数
  27. char ciCompress[4];//压缩说明
  28. char ciSizeImage[4];//用字节表示的图像大小,该数据必须是4的倍数
  29. char ciXPelsPerMeter[4];//目标设备的水平像素数/米
  30. char ciYPelsPerMeter[4];//目标设备的垂直像素数/米
  31. char ciClrUsed[4]; //位图使用调色板的颜色数
  32. char ciClrImportant[4]; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
  33. }__attribute__((packed)) BITMAPINFOHEADER;
  34. typedef struct
  35. {
  36. unsigned short blue;
  37. unsigned short green;
  38. unsigned short red;
  39. unsigned short reserved;
  40. }__attribute__((packed)) PIXEL;//颜色模式RGB
  41. BITMAPFILEHEADER FileHead;
  42. BITMAPINFOHEADER InfoHead;
  43. static char *fbp = 0;
  44. static int xres = 0;
  45. static int yres = 0;
  46. static int bits_per_pixel = 0;
  47. int show_bmp();
  48. int main ( int argc, char *argv[] )
  49. {
  50. int fbfd = 0;
  51. struct fb_var_screeninfo vinfo;
  52. struct fb_fix_screeninfo finfo;
  53. long int screensize = 0;
  54. struct fb_bitfield red;
  55. struct fb_bitfield green;
  56. struct fb_bitfield blue;
  57. //打开显示设备
  58. fbfd = open("/dev/fb0", O_RDWR);
  59. if (!fbfd)
  60. {
  61. printf("Error: cannot open framebuffer device.\n");
  62. exit(1);
  63. }
  64. if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))
  65. {
  66. printf("Error:reading fixed information.\n");
  67. exit(2);
  68. }
  69. if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
  70. {
  71. printf("Error: reading variable information.\n");
  72. exit(3);
  73. }
  74. printf("R:%d,G:%d,B:%d \n", vinfo.red, vinfo.green, vinfo.blue );
  75. printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
  76. xres = vinfo.xres;
  77. yres = vinfo.yres;
  78. bits_per_pixel = vinfo.bits_per_pixel;
  79. //计算屏幕的总大小(字节)
  80. screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
  81. printf("screensize=%d byte\n",screensize);
  82. //对象映射
  83. fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
  84. if ((int)fbp == -1)
  85. {
  86. printf("Error: failed to map framebuffer device to memory.\n");
  87. exit(4);
  88. }
  89. printf("sizeof file header=%d\n", sizeof(BITMAPFILEHEADER));
  90. printf("into show_bmp function\n");
  91. //显示图像
  92. show_bmp();
  93. //删除对象映射
  94. munmap(fbp, screensize);
  95. close(fbfd);
  96. return 0;
  97. }
  98. int show_bmp()
  99. {
  100. FILE *fp;
  101. int rc;
  102. int line_x, line_y;
  103. long int location = 0, BytesPerLine = 0;
  104. char tmp[1024*10];
  105. fp = fopen( "./niu.bmp", "rb" );
  106. if (fp == NULL)
  107. {
  108. return( -1 );
  109. }
  110. rc = fread( &FileHead, sizeof(BITMAPFILEHEADER),1, fp );
  111. if ( rc != 1)
  112. {
  113. printf("read header error!\n");
  114. fclose( fp );
  115. return( -2 );
  116. }
  117. //检测是否是bmp图像
  118. if (memcmp(FileHead.cfType, "BM", 2) != 0)
  119. {
  120. printf("it's not a BMP file\n");
  121. fclose( fp );
  122. return( -3 );
  123. }
  124. rc = fread( (char *)&InfoHead, sizeof(BITMAPINFOHEADER),1, fp );
  125. if ( rc != 1)
  126. {
  127. printf("read infoheader error!\n");
  128. fclose( fp );
  129. return( -4 );
  130. }
  131. //跳转的数据区
  132. fseek(fp, FileHead.cfoffBits, SEEK_SET);
  133. //每行字节数
  134. BytesPerLine = (InfoHead.ciWidth * InfoHead.ciBitCount + 31) / 32 * 4;
  135. line_x = line_y = 0;
  136. //向framebuffer中写BMP图片
  137. while(!feof(fp))
  138. {
  139. PIXEL pix;
  140. unsigned short int tmp;
  141. rc = fread( (char *)&pix, 1, sizeof(PIXEL), fp);
  142. if (rc != sizeof(PIXEL))
  143. break;
  144. location = line_x * bits_per_pixel / 8 + (InfoHead.ciHeight - line_y - 1) * xres * bits_per_pixel / 8;
  145. //显示每一个像素
  146. *(fbp + location + 0)=pix.blue;
  147. *(fbp + location + 1)=pix.green;
  148. *(fbp + location + 2)=pix.red;
  149. *(fbp + location + 3)=pix.reserved;
  150. line_x++;
  151. if (line_x == InfoHead.ciWidth )
  152. {
  153. line_x = 0;
  154. line_y++;
  155. if(line_y == InfoHead.ciHeight)
  156. break;
  157. }
  158. }
  159. fclose( fp );
  160. return( 0 );
  161. }

注意:上面的程序只在framebuffer上显示图片,却没有删除刷新屏幕,可以使用下面的命令恢复屏幕

保存屏幕信息:dd if=/dev/fb0 of=fbfile  或: cp /dev/fb0 fbfile

恢复屏幕信息:dd if=fbfile of=/dev/fb0  或: cat fbfile > /dev/fb0

Linux framebuffer显示bmp图片【转】的更多相关文章

  1. MFC对话框显示BMP图片

    1.MFC对话框显示BMP图片我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) ...

  2. 【秒懂音视频开发】21_显示BMP图片

    文本的主要内容是:使用SDL显示一张BMP图片,算是为后面的<播放YUV>做准备. 为什么是显示BMP图片?而不是显示JPG或PNG图片? 因为SDL内置了加载BMP的API,使用起来会更 ...

  3. 嵌入式linux------SDL移植(am335x下显示bmp图片)

    #include<stdio.h> #include "/usr/local/ffmpeg_arm/include/SDL/SDL.h" char *bmp_name[ ...

  4. OPENGL 显示BMP图片+旋转

    VS2010/Windows 7/ 1. 需包含头文件 stdio.h, glaux.h, glut.h.需要对应的lib,并添加包含路径 2. 窗口显示用glut库的函数 3. bmp图片从本地读取 ...

  5. MFC CListCtrl 显示bmp图片

    m_ListCtrl.SetExtendedStyle(m_ListCtrl.GetExtendedStyle()| LVS_EX_SUBITEMIMAGES | LVS_EX_GRIDLINES); ...

  6. VC加载显示bmp图片的函数

    void ShowBitmap(HDC hdc,const char *srcpath) { HBITMAP hBitmap = (HBITMAP)::LoadImage(0, srcpath, IM ...

  7. MFC对话框中显示BMP,JPG图片

    //************************************ // 方法说明:    显示JPG和GIF.BMP图片 // 参数说明:    CDC * pDC           设 ...

  8. MFC 对话框Picture Control(图片控件)中静态和动态显示Bmp图片

    版权声明:本文为博主原创文章,转载请注明CSDN博客源地址! 共同学习,一起进步~ https://blog.csdn.net/Eastmount/article/details/26404733   ...

  9. MFC显示bmp图像

    有了bmp文件读写的基础,我们就能够開始用MFC显示BMP图片了. 在这里,事实上微软为我们提供了一个实现bmp文件显示的框架,名叫diblook,我们能够先下载下来看看. 以下上链接:DIBLOOK ...

随机推荐

  1. 完整版本的停车场管理系统源代码带服务端+手机android客户端

    该源码是停车场管理软件附带源代码 J2EE服务端+android客户端,也是一套停车场管理车辆进出的管理软,喜欢的朋友可以看看吧. 应用的后台管理主要功能介绍:1  机构管理 ,机构有从属管理< ...

  2. git——merge和rebase的区别

    参考http://www.jianshu.com/p/129e721adc6e 我在公司里看到其他同事都使用git pull --rebase拉取远程代码,而我总是用git pull,也有同事和我说过 ...

  3. Android项目实战_手机安全卫士进程管理

    ###1.设备进程信息获取获取设备运行进程 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVI ...

  4. [Windows Server 2012] 安装护卫神·主机管理系统

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装护卫神·主 ...

  5. 我的 Windows 10 的基本配置

    Windows 10 的基本配置 功能性 开启 .Net Framework 3.5(包括 .NET 2.0 和 3.0) 旧版本 Windows 10 默认只安装了 .Net Framework 4 ...

  6. ionic 创建某个文件下的page

    ionic g page 文件名 --pagesDir src/pages/about

  7. 前端领域的BEM到底是什么

    前端领域的BEM到底是什么 BEM - Block Element Modfier(块元素编辑器) BEM方法确保每一个参加了同一网站开发项目的人,基于一套代码规范去开发,这样非常有利于团队成员理解彼 ...

  8. Git使用笔记 (github为例)

    ---`Git`# Git管理 #- 创建仓库 git init 在本地目录下建立新git仓库,该仓库可以为空也可以是重新初始化的仓库.该命令将创建一个名为 .git 的子目录,这个子目录含有初始化的 ...

  9. c# SQL事务

    SQL事务执行 SqlTransaction   sqlTransaction   =   sqlConnection.BeginTransaction();    SqlCommand   sqlC ...

  10. bupt summer training for 16 #5 ——数据结构

    https://vjudge.net/contest/173780 A.假设 Pt = i,则由Ppi = i得 Ppt = t = Pi 所以就有 if Pt = i then Pi = t #in ...