本文转载自: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. 给网站添加运行时间的JavaScript完整代码

    function secondToDate(second) { if (!second) { return 0; } var time = new Array(0, 0, 0, 0, 0); if ( ...

  2. Android基础TOP2_1:输出系统时间

    Activity: <TextView android:id="@+id/tv" android:layout_width="wrap_content" ...

  3. PB连接SQLITE

    sqlite3数据库,简单而功能强大,比起ini文件保存用户设置,更简单安全,为什么使用数据库存用户设置,由开发者自己去想吧进入话题:pb中可以用ole DB方式在不注册odbc的情况下直接连接数据库 ...

  4. python调用java API

    JPype documentation JPype is an effort to allow python programs full access to java class libraries. ...

  5. FusionCharts 更新 chart data 数据

    var AlarmChart = null; function alarmChartReBuild(totalNum, alarmNum) { var alarmPart = (alarmNum * ...

  6. PHP 数据库连接 (Mysql Mysqli PDO)

    1.PHP与Mysql扩展(本扩展自 PHP 5.5.0 起已废弃,并在将来会被移除),PHP原生的方式去连接数据库,是面向过程的 <?php $mysql_conf = array( 'hos ...

  7. 安装hiredis后swoole扩展消失

    php -m报错: PHP Warning: PHP Startup: Unable to load dynamic library 'swoole' (tried: /home/work/study ...

  8. leetcode刷题记录--js

    leetcode刷题记录 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但 ...

  9. Uncaught TypeError: str.replace is not a function

    在做审核页面时,点击审核通过按钮不执行 后来F12控制台查看发现有报错 是因为flisnullandxyzero未执行 然后找出这个方法,此方法为公共方法,将这个方法复制出来 然后使用console. ...

  10. ModelBinder 请求容错性

    代码 //using System.Web.Mvc; public class TrimToDBCModelBinder : DefaultModelBinder { public override ...