天天看點

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. typedef struct  
  44. {  
  45.   char rgbBlue;  
  46.   char rgbGreen;  
  47.   char rgbRed;  
  48.   char rgbReserved;  
  49. } RGBQUAD;  
  50. BITMAPFILEHEADER FileHead;  
  51. BITMAPINFOHEADER InfoHead;  
  52. RGBQUAD          rgbquad;  
  53. int  show_bmp (char *bmpfile );  
  54. long chartolong(char * string, int length );  
  55. struct fb_var_screeninfo vinfo;  
  56. struct fb_fix_screeninfo finfo;                                                                                  
  57. int fb_init()  
  58. {  
  59.    //struct fb_var_screeninfo vinfo;  
  60.    //struct fb_fix_screeninfo finfo;  
  61.    struct fb_bitfield red;//bitfield in fb mem if true colour  
  62.    struct fb_bitfield green;//else only length is significant  
  63.    struct fb_bitfield blue;  
  64.    fbfd=open("/dev/fb0",O_RDWR);  
  65.    if(!fbfd)  
  66.    {  
  67.       printf("erro:cannot open the dev/n");  
  68.       exit(1);  
  69.    }  
  70.    else  
  71.       //printf("the dev is opened successfully/n");  
  72.    if(ioctl(fbfd,FBIOGET_FSCREENINFO,&finfo)==-1)  
  73.    {  
  74.       printf("erro reading fixed screen/n");  
  75.       exit(2);  
  76.    }  
  77.    if(ioctl(fbfd,FBIOGET_VSCREENINFO,&vinfo)==-1)  
  78.    {  
  79.       printf("erro reading variable info/n");  
  80.       exit(3);  
  81.    }  
  82.    xres  = vinfo.xres;  
  83.    yres  = vinfo.yres;  
  84.    red   = vinfo.red;  
  85.    green = vinfo.green;  
  86.    blue  = vinfo.blue;  
  87.    bits_per_pixel=vinfo.bits_per_pixel;  
  88.    //printf("vifo.xres=%d/n",xres);  
  89.    //printf("vifo.yres=%d/n",yres);  
  90.    // printf("vifo.bits_per_bits=%d/n",bits_per_pixel);  
  91.    //printf("vifo.xoffset=%d/n",vinfo.xoffset);  
  92.    // printf("vifo.yoffset=%d/n",vinfo.yoffset);  
  93.    // printf("finfo.line_length=%d/n",finfo.line_length);  
  94.    screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;  
  95.    fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fbfd,0);  
  96.    if((int)fbp==-1)  
  97.    {  
  98.       printf("erro:failed to map framebuffer/n");  
  99.       exit(4);  
  100.    }  
  101.    else printf ("the framebuffer device was mapped to menory successfully/n");  
  102.    memset(fbp,0,screensize);  
  103.    return 0;  
  104. }  
  105. void fb_close()  
  106. {   
  107.     munmap(fbp,screensize);  
  108.     close(fbfd);  
  109. }  
  110. long chartolong(char *string,int length)  
  111.  {  
  112.         long number;  
  113.         if(length<=4)  
  114.                 {  
  115.                         memset(&number,0x00,sizeof(long));  
  116.                         memcpy(&number,string,length);                               //  
  117.                 }  
  118.           return (number);  
  119.   }  
  120. int show_bmp(char *bmpfile)  
  121. {  
  122.     FILE *fp;  
  123.     int  rc;  
  124.     int  ciBitCount,ciWidth,ciHeight;  
  125.     int  line_x,line_y;  
  126.     long int location=0,BytesPerLine=0;  
  127.     char tmp[1024*10];  
  128.      fp=fopen(bmpfile,"rb");  
  129.      if(fp==NULL) return (-1);  
  130. //read the bmp head  
  131.      rc = fread(&FileHead,1,sizeof(BITMAPFILEHEADER),fp);  
  132.      if(rc!=sizeof(BITMAPFILEHEADER))  
  133.      {  
  134.          fclose(fp);  
  135.          return(-2);  
  136.      }  
  137.      if(memcmp(FileHead.cfType,"BM",2)!=0)  
  138.      {  
  139.          fclose(fp);  
  140.          return(-3);  
  141.      }  
  142.      rc=fread((char*)&InfoHead,1,sizeof(BITMAPINFOHEADER),fp);  
  143.      if(rc!=sizeof(BITMAPINFOHEADER))  
  144.      {  
  145.          fclose(fp);  
  146.          return(-4);  
  147.      }  
  148.      ciWidth=(int)chartolong(InfoHead.ciWidth,4);  
  149.      ciHeight=(int)chartolong(InfoHead.ciHeight,4);  
  150.      ciBitCount=(int)chartolong(InfoHead.ciBitCount,4);  
  151.      line_x=line_y=0;  
  152.      while(!feof(fp))  
  153.      {   
  154.           rc=fread((char*)&rgbquad,1,sizeof(RGBQUAD),fp);  
  155.           if(rc!=sizeof(RGBQUAD)) break;  
  156.           location=(line_x+200)*bits_per_pixel/8+ (ciHeight-line_y+150)*finfo.line_length;      
  157.           //printf("location= %d/n", location) ;  
  158.           *(fbp + location + 0)=rgbquad.rgbBlue;  
  159.           *(fbp + location + 1)=rgbquad.rgbGreen;  
  160.           *(fbp + location + 2)=rgbquad.rgbRed;  
  161.           *(fbp + location + 3)=rgbquad.rgbReserved;  
  162.           line_x++ ;  
  163.           if(line_x==(ciWidth))  
  164.           {  
  165.                line_x=0;  
  166.                line_y++ ;  
  167.           }  
  168.       }  
  169.       fclose(fp);  
  170.       return(0);  
  171. }  
  172. int main(int argc,char *argv[])  
  173. {  
  174.        int x=0;   
  175.        int y=0;  
  176.        fb_init();  
  177.        show_bmp(argv[1]);  
  178.        return 0;  
  179. }  

追加内容: 說到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

繼續閱讀