Ubuntu 9.10 实现用framebuffer显示bmp图片

在命令行下利用framebuffer显示bmp格式的图片,首先要打开framebuffer设备,ubuntu 9.10 是打开/boot/grub/grub.cfg 文件 在“linux    /boot/vmlinuz-2.6.31-22-generic root=UUID=dadb1e1d-b7b7-45c8-a031-21d2e840c608 ro   quiet splash  vga=791 " 这一行加入红字,注意不是recovery mode 。 然后重启就打开了framebuffer设备,在/dev下可以看到fb0。下面是程序代码。要注意显示的图片的位数(有16位24位和32位的)这个是显示32位bmp图片的。

[cpp]  view plain copy
  1. #include<unistd.h>  
  2. #include<stdio.h>  
  3. #include<fcntl.h>  
  4. #include<linux/fb.h>  
  5. #include<sys/mman.h>  
  6. #include<stdlib.h>  
  7. #include<sys/ioctl.h>  
  8. #include<asm/page.h>  
  9. #include <string.h>  
  10. #include <errno.h>  
  11. #include <unistd.h>  
  12. #include <linux/kd.h>  
  13. #include <linux/keyboard.h>   
  14. #include <termios.h>  
  15.   static int fbfd=0;  
  16.   static long int screensize=0;  
  17.   static char *fbp=0;  
  18.   int x=0,y=0;  
  19.   long int location =0;  
  20.   static int xres=0,yres=0;  
  21.   int bits_per_pixel=0;  
  22. typedef struct  
  23. {  
  24.   char cfType[2];        // file type  
  25.   char cfSize[4];        // file size  
  26.   char cfReserved[4];    //  
  27.   char cfoffBits[4];     //  
  28. }BITMAPFILEHEADER;       //file head strucgt  
  29. typedef struct  
  30. {  
  31.   char ciSize[4];                   //  
  32.   char ciWidth[4];  
  33.   char ciHeight[4];  
  34.   char ciPlanes[2];  
  35.   char ciBitCount[2];  
  36.   char ciCompress[4];  
  37.   char ciSizeImage[4];  
  38.   char ciXPelsPerMeter[4];  
  39.   char ciYPelsPerMeter[4];  
  40.   char ciClrUsed[4];  
  41.   char ciClrImportant[4];  
  42. } BITMAPINFOHEADER;  
  43.                                                                                   
  44.                                                                                   
  45. typedef struct  
  46. {  
  47.   char rgbBlue;  
  48.   char rgbGreen;  
  49.   char rgbRed;  
  50.   char rgbReserved;  
  51. } RGBQUAD;  
  52.                                                                                   
  53. BITMAPFILEHEADER FileHead;  
  54. BITMAPINFOHEADER InfoHead;  
  55. RGBQUAD          rgbquad;  
  56.                                                                                   
  57. int  show_bmp (char *bmpfile );  
  58. long chartolong(char * string, int length );  
  59. struct fb_var_screeninfo vinfo;  
  60. struct fb_fix_screeninfo finfo;                                                                                  
  61. int fb_init()  
  62. {  
  63.    //struct fb_var_screeninfo vinfo;  
  64.    //struct fb_fix_screeninfo finfo;  
  65.    struct fb_bitfield red;//bitfield in fb mem if true colour  
  66.    struct fb_bitfield green;//else only length is significant  
  67.    struct fb_bitfield blue;  
  68.    /*open the dev */  
  69.    fbfd=open("/dev/fb0",O_RDWR);  
  70.    if(!fbfd)  
  71.    {  
  72.       printf("erro:cannot open the dev/n");  
  73.       exit(1);  
  74.    }  
  75.    else  
  76.       //printf("the dev is opened successfully/n");  
  77.    /*get sreeen information*/  
  78.    if(ioctl(fbfd,FBIOGET_FSCREENINFO,&finfo)==-1)  
  79.    {  
  80.       printf("erro reading fixed screen/n");  
  81.       exit(2);  
  82.    }  
  83.    /*get variable sreen info*/  
  84.    if(ioctl(fbfd,FBIOGET_VSCREENINFO,&vinfo)==-1)  
  85.    {  
  86.       printf("erro reading variable info/n");  
  87.       exit(3);  
  88.    }  
  89.    /*init the parse*/  
  90.    xres  = vinfo.xres;  
  91.    yres  = vinfo.yres;  
  92.    red   = vinfo.red;  
  93.    green = vinfo.green;  
  94.    blue  = vinfo.blue;  
  95.    bits_per_pixel=vinfo.bits_per_pixel;  
  96.    /*show these information*/  
  97.    //printf("vifo.xres=%d/n",xres);  
  98.    //printf("vifo.yres=%d/n",yres);  
  99.    // printf("vifo.bits_per_bits=%d/n",bits_per_pixel);  
  100.    //printf("vifo.xoffset=%d/n",vinfo.xoffset);  
  101.    // printf("vifo.yoffset=%d/n",vinfo.yoffset);  
  102.    // printf("finfo.line_length=%d/n",finfo.line_length);  
  103.                                                                                   
  104.    /*figure out the size of screen in bytes*/  
  105.    screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;  
  106.    /*map the device to memory*/  
  107.    fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fbfd,0);  
  108.    if((int)fbp==-1)  
  109.    {  
  110.       printf("erro:failed to map framebuffer/n");  
  111.       exit(4);  
  112.    }  
  113.    else printf ("the framebuffer device was mapped to menory successfully/n");  
  114.     
  115.    memset(fbp,0,screensize);  
  116.    return 0;  
  117. }  
  118.                                                                                   
  119. void fb_close()  
  120. {   
  121.     munmap(fbp,screensize);  
  122.     close(fbfd);  
  123. }  
  124. long chartolong(char *string,int length)  
  125.  {  
  126.         long number;  
  127.         if(length<=4)  
  128.                 {  
  129.                         memset(&number,0x00,sizeof(long));  
  130.                         memcpy(&number,string,length);                               //  
  131.                 }  
  132.           return (number);  
  133.   }  
  134. int show_bmp(char *bmpfile)  
  135. {  
  136.                                                                                   
  137.     FILE *fp;  
  138.     int  rc;  
  139.     int  ciBitCount,ciWidth,ciHeight;  
  140.     int  line_x,line_y;  
  141.     long int location=0,BytesPerLine=0;  
  142.     char tmp[1024*10];  
  143. /*open the bmp file*/  
  144.      fp=fopen(bmpfile,"rb");  
  145.      if(fp==NULL) return (-1);  
  146.        
  147. //read the bmp head  
  148.      rc = fread(&FileHead,1,sizeof(BITMAPFILEHEADER),fp);  
  149.      if(rc!=sizeof(BITMAPFILEHEADER))  
  150.      {  
  151.          fclose(fp);  
  152.          return(-2);  
  153.      }  
  154.      if(memcmp(FileHead.cfType,"BM",2)!=0)  
  155.      {  
  156.          fclose(fp);  
  157.          return(-3);  
  158.      }  
  159.      rc=fread((char*)&InfoHead,1,sizeof(BITMAPINFOHEADER),fp);  
  160.      if(rc!=sizeof(BITMAPINFOHEADER))  
  161.      {  
  162.          fclose(fp);  
  163.          return(-4);  
  164.      }  
  165.      ciWidth=(int)chartolong(InfoHead.ciWidth,4);  
  166.      ciHeight=(int)chartolong(InfoHead.ciHeight,4);  
  167.      ciBitCount=(int)chartolong(InfoHead.ciBitCount,4);  
  168.      line_x=line_y=0;  
  169.      while(!feof(fp))  
  170.      {   
  171.           rc=fread((char*)&rgbquad,1,sizeof(RGBQUAD),fp);  
  172.           if(rc!=sizeof(RGBQUAD)) break;  
  173.     
  174.           location=(line_x+200)*bits_per_pixel/8+ (ciHeight-line_y+150)*finfo.line_length;      
  175.           //printf("location= %d/n", location) ;  
  176.           *(fbp + location + 0)=rgbquad.rgbBlue;  
  177.           *(fbp + location + 1)=rgbquad.rgbGreen;  
  178.           *(fbp + location + 2)=rgbquad.rgbRed;  
  179.           *(fbp + location + 3)=rgbquad.rgbReserved;  
  180.             
  181.           line_x++ ;  
  182.             
  183.           if(line_x==(ciWidth))  
  184.           {  
  185.                line_x=0;  
  186.                line_y++ ;  
  187.          
  188.           }  
  189.       }  
  190.       fclose(fp);  
  191.       return(0);  
  192. }  
  193. int main(int argc,char *argv[])  
  194. {  
  195.        int x=0;   
  196.        int y=0;  
  197.        fb_init();  
  198.        show_bmp(argv[1]);  
  199.        return 0;  
  200.          
  201.                                                                                   
  202. }  

 

追加内容: 说到framebuffer 不得不说到一个函数ioctl ,这里只是简单用了一下,ioctl中第二个参数是cmd,比如FBIOGET_FSCREENINFO,FBIOGET_VSCREENINFO,分别是获取fbfd设备的固定信息和可改变信息,FBIOPUT_VSCREENINFO 用户设置可变屏幕参数,FBIOPUTCMAP 设置屏幕颜色表,FBIOGETCMAP 获取颜色表等。

         还有个函数mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)  与之对应的是 int munmap(void *start ,size_t length)

start 是映射区开始地址, length 映射区的长度(字节),prot 期望内存保护标志,如(PROT_EXEC ,PROT_READ, PROT_WRITE, PROT_NONE) flags 指定映射对象的类型 它的值有MAP_FIXED 使用指定得映射地址,MAP_SHARED 与其它映射这个对象的进程共享映射空间,这个值不能与MAP_PRIVATE 不能同时用。MAP_LOCKED 锁定映射区的页面,防止交换内存。fd 有效文件描述词。offset 映射对象内容的起点。

mmap 成功执行返回文件映射到进程空间的地址,失败返回-1

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值