Linux framebuffer显示bmp图片

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显示一张图片:

[cpp] view plaincopy

  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

From:http://blog.csdn.net/luxiaoxun/article/details/7622988

Linux framebuffer显示bmp图片,码迷,mamicode.com

时间: 2024-10-11 15:55:47

Linux framebuffer显示bmp图片的相关文章

Linux framebuffer显示bmp图片【转】

本文转载自:http://blog.csdn.net/luxiaoxun/article/details/7622988 framebuffer简介 帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作.framebuffer是LCD对应的一中HAL(硬件抽象层),提供抽象的,统一的接口操作,用户不必关心硬件层是怎么实施的.这些都是由Framebuffer设备驱动来完成的.     帧缓冲设备对应

MFC对话框显示BMP图片

1.MFC对话框显示BMP图片我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基于对话框的工程,名为Ttest. 对话框类为CTestDlg (一)    非动态载入图片. 方法1.先从最简单的开始,用picture 控件来实现. 步骤: 先在资源里Import一张图片,ID为IDB_BITMAP2 然后在对话框上添加一个picture控件,右键点

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

#include<stdio.h> #include "/usr/local/ffmpeg_arm/include/SDL/SDL.h" char *bmp_name[3] = {"000.bmp","111.bmp","222.bmp"}; int main() { int i=0; //The images SDL_Surface* hello = NULL; SDL_Surface* screen = NUL

OPENGL 显示BMP图片+旋转

VS2010/Windows 7/ 1. 需包含头文件 stdio.h, glaux.h, glut.h.需要对应的lib,并添加包含路径 2. 窗口显示用glut库的函数 3. bmp图片从本地读取,再用它来生成纹理,首先用auxDIBImageLoad函数将图片数据读到AUX_RGBImageRec结构体当中. 然后 //生成纹理数据 glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->siz

MFC CListCtrl 显示bmp图片

m_ListCtrl.SetExtendedStyle(m_ListCtrl.GetExtendedStyle()| LVS_EX_SUBITEMIMAGES | LVS_EX_GRIDLINES); m_ListCtrl.InsertColumn(0, L"#", LVCFMT_CENTER, 0); m_ListCtrl.InsertColumn(1,_T("T1"),LVCFMT_LEFT,100); m_ListCtrl.InsertColumn(2,_T(

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

最近有同学问我如何实现MFC基于对话框在图片控件中加载图片?其实使用MFC显示图片的方法各种各样,但是还是有些同学不知道怎样显示.以前在<数字图像处理>课程中完成的软件都是基于单文档的程序,这里介绍两种在对话框picthre控件中显示BMP图片的最简单基础的方法. ~~方法可能并不完美,高手忽略,但是提供一种能运行的方法,希望对刚接触这方面知识的同学有所帮助.可能你觉得文章过于简单或者有些过于详细叙述(点到即可我并不反对),但也为哪些入门同学想想,当初自己也是一头雾水. 一.静态显示bmp图片

提取bmp图片的颜色信息,可直接framebuffer显示

稍微了解了下linux的framebuffer,这是一种很简单的显示接口,直接写入像素信息即可 配置好的内核,会有/dev/fbn 的接口,于是想能否提前生成一个文件,比如logo.fb,里面仅包含像素信息,从而可以直接送入framebuffer显示 搜索了一下,有不少文章介绍,如何解析bmp图片并送给framebuffer显示,但没有找到预处理工具,都是直接处理完就送入framebuffer 于是参考了一篇文章,改动了下代码,将直接送入framebuffer变成写到一个文件中. 原代码地址为

Linux LCD 显示图片【转】

转自:https://blog.csdn.net/niepangu/article/details/50528190 BMP和JPEG图形显示程序1)  在LCD上显示BMP或JPEG图片的主流程图首先,在程序开始前.要在nfs/dev目录下创建LCD的设备结点,设备名fb0,设备类型为字符设备,主设备号为29,次设备号为0.命令如下:mknod fb0 c 29 0在LCD上显示图象的主流程图如图1所示.程序一开始要调用open函数打开设备,然后调用ioctl获取设备相关信息,接下来就是读取图

bmp图片显示

文件IO项目: 在开发板屏幕上循环显示目录里的图片 a.按照一定的间隔循环显示目录里的bmp图片 b.实现手指滑动来显示目录里的图片(bmp,jpg)上一张,下一张 d1: 1.能操控屏幕(查询开发板屏幕分辨率,以及每个像素点占几个字节) 命令:FBIOGET_VSCREENINFO 查询结果保存在些结构中: struct fb_var_screeninfo fbinfo; __u32 xres; 屏幕分辨率 __u32 yres; __u32 bits_per_pixel; 每个像素点占多少位