framebuffer 保存 bmp图片格式

最近需要完成一个从framebuffer中进行读取,然后将内存的东西保存为bmp图片格式,我的其他博客内容对framebuffer进行详细的讲解,以及bmp的格式进行详细的讲解。

    之前从网上看到了一些保存bmp图片的代码,在本地执行都会出现问题,本人就进行了自己编写,可以指定文件的文件名和文件类型

   也可以从github中获取源码:

直接看代码:https://github.com/Guazhen/Framebuffer_shot



[cpp]  view plain  copy
  1. #include <linux/fb.h>  
  2. #include <stdio.h>  
  3. #include <stdint.h>   
  4. #include <fcntl.h>  
  5. #include <sys/mman.h>  
  6. #include <sys/ioctl.h>   
  7. #include <getopt.h>  
  8. #include <strings.h>  
  9. #include <unistd.h>  
  10. typedef unsigned short WORD;  
  11. typedef unsigned int DWORD;  
  12. typedef unsigned long LONG;  
  13.   
  14. typedef struct tagBITMAPFILEHEADER {  
  15.     WORD bfType;  
  16.     DWORD bfSize;  
  17.     WORD bfReserved1;  
  18.     WORD bfReserved2;  
  19.     DWORD bfOffBits;   
  20. } __attribute__((packed)) BITMAPFILEHEADER;  
  21.   
  22.   
  23. typedef struct tagBITMAPINFOHEADER  
  24. {  
  25.     DWORD biSize; /*info header size in bytes*/  
  26.     DWORD biWidth; /*widht of image*/  
  27.     DWORD biHeight;/*height of image*/  
  28.     WORD biPlanes;/*number of colour planes*/   
  29.     WORD biBitCount;/*bits per pixel*/  
  30.     DWORD biCompression;/*compression type*/  
  31.     DWORD biSizeImage;/*image size meter*/  
  32.     DWORD biXPelsPerMeter;/*pixels per meter*/  
  33.     DWORD biYPelsPerMeter;/*pexels per meter*/  
  34.     DWORD biClrUsed;/*number of colour*/  
  35.     DWORD biClrImportant;/*important colour*/  
  36. } __attribute__((packed)) BITMAPINFOHEADER;  
  37.   
  38. int output_file;  
  39. int type_file;  
  40.   
  41. struct fb_fix_screeninfo finfo;  
  42. struct fb_var_screeninfo vinfo;  
  43.   
  44. static const struct option long_options[]=    
  45. {    
  46.      {"output",1,NULL,'o'},    
  47.      {"t",1,NULL,'t'},      
  48.      {NULL,0,NULL,0}    
  49. };   
  50.   
  51. static void usage(void)    
  52. {    
  53.     fprintf(stderr,    
  54.             "imax6 [option]...\n"    
  55.             "  -o|--output               Output the filename.\n"    
  56.             "  -t|--type               Output the type of thefilename.\n"  
  57.             "  -h|--help               help information.\n"  
  58.            );    
  59. };  
  60.   
  61.   
  62. static void image_bmp( const char *filename)  
  63. {  
  64.     printf("starting bmp..\n");  
  65.     char tmpbufilename[126] = {0};  
  66.     if( NULL != filename)  
  67.     {  
  68.         strcpy(tmpbufilename, filename);                  
  69.         strcat(tmpbufilename,".bmp");  
  70.     }else  
  71.     {  
  72.         strcpy(tmpbufilename,"screen.bmp");  
  73.     }  
  74.       
  75.     FILE *fp;  
  76.     BITMAPFILEHEADER    bmfh;  
  77.         BITMAPINFOHEADER    bmih;  
  78.   
  79.         ((unsigned char *)&bmfh.bfType)[0] = 'B';  
  80.         ((unsigned char *)&bmfh.bfType)[1] = 'M';  
  81.   
  82.         bmfh.bfSize =  sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + vinfo.yres * vinfo.xres * 4;  
  83.         bmfh.bfReserved1 = 0;  
  84.         bmfh.bfReserved2 = 0;  
  85.         bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  86.   
  87.         bmih.biSize = sizeof(BITMAPINFOHEADER);  
  88.   
  89.         bmih.biWidth = vinfo.xres;  
  90.         bmih.biHeight = vinfo.yres;  
  91.         bmih.biPlanes = 1;  
  92.         bmih.biBitCount = 32;  
  93.         bmih.biCompression = 0;  
  94.         bmih.biSizeImage = 0; /*说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0*/  
  95.         bmih.biXPelsPerMeter = 0; /*缺省值*/  
  96.         bmih.biYPelsPerMeter = 0;  
  97.         bmih.biClrUsed = 0; /*说明位图实际使用的调色板索引数,0:使用所有的调色板索引*/  
  98.         bmih.biClrImportant = 0; /*说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要*/  
  99.   
  100.     printf("tmpbufilename = %s\n",tmpbufilename);  
  101.   
  102.         FILE* image_file = fopen(tmpbufilename,"a");  
  103.     if( NULL == image_file)  
  104.     {  
  105.         printf("image fopen fail\n");  
  106.     }  
  107.   
  108.         fwrite(&bmfh, sizeof(BITMAPFILEHEADER),1,image_file);  
  109.         fwrite(&bmih, sizeof(BITMAPINFOHEADER),1,image_file);  
  110.   
  111.         FILE *raw_file = fopen( "test.raw","rb");  
  112.     if( NULL == raw_file)     
  113.     {  
  114.         printf("rawfile fopen fail..\n");  
  115.     }  
  116.       
  117.       
  118.     /* 
  119.     fgetc是一种计算机语言中的函数。意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。格式:int fgetc(FILE *stream); 
  120.     */  
  121.      
  122.         //int ch = fgetc(raw_file);  
  123.     int ch = getc(raw_file);  
  124.       
  125.     /* 
  126.  
  127.     for(y = 0; y < vinfo.yres; y+) 
  128.     {   
  129.         for(x = 0; x < vinfo.xres; x++)   
  130.         {   
  131.             long location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y + vinfo.yoffset) * finfo.line_length;              
  132.             write(image_file, fbp + location, 4);   
  133.         }   
  134.     }    
  135.     */  
  136.     int x, y;  
  137.     for( y = vinfo.yres - 1; y >= 0; y--)  
  138.     {  
  139.         for(x = 0; x < vinfo.xres; x++)  
  140.         {  
  141.             /*字节数*/  
  142.             long location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y + vinfo.yoffset) * finfo.line_length;  
  143.             fseek(raw_file, location, SEEK_SET);  
  144.             ch = fgetc(raw_file);  
  145.             fputc(ch,image_file);  
  146.   
  147.             ch = fgetc(raw_file);  
  148.             fputc(ch,image_file);  
  149.   
  150.             ch = fgetc(raw_file);  
  151.             fputc(ch,image_file);  
  152.   
  153.             ch = fgetc(raw_file);  
  154.             fputc(ch,image_file);   
  155.         }  
  156.     }  
  157.     /* 
  158.     while( ch != EOF) 
  159.         { 
  160.         ch = fgetc(raw_file); 
  161.                 fputc(ch,image_file); 
  162.          
  163.         ch = fgetc(raw_file); 
  164.                 fputc(ch,image_file); 
  165.  
  166.         ch = fgetc(raw_file); 
  167.                 fputc(ch,image_file); 
  168.  
  169.         ch = fgetc(raw_file); 
  170.                 fputc(ch,image_file);                 
  171.         }*/  
  172.   
  173.         fp = popen("rm ./test.raw","r");  
  174.         pclose(fp);  
  175.   
  176.     fclose(raw_file);  
  177.     fclose(image_file);  
  178.     printf("ending bmp\n");  
  179. }  
  180.   
  181. int main(int argc, char **argv)  
  182. {  
  183.     int opt = 0;  
  184.     int options_index = 0;  
  185.     char *tmp = NULL;  
  186.     char filename[126] = {0};  
  187.     char type[126] = {0};  
  188.   
  189.     if(argc == 1)  
  190.     {  
  191.         usage();  
  192.         return 2;     
  193.     }  
  194.     /* 解析命令行参数*/  
  195.     while((opt=getopt_long(argc,argv,"o:t:h?",long_options,&options_index))!=EOF )    
  196.     {    
  197.         switch(opt)    
  198.         {      
  199.             case 'o':   
  200.                 output_file=1;  
  201.                 sprintf(filename,"%s",optarg);  
  202.                 break;    
  203.             case 't':   
  204.                 type_file=1;  
  205.                 sprintf(type,"%s",optarg);  
  206.                 break;     
  207.             case 'h':    
  208.             case '?':   
  209.                 usage();return 2;break;    
  210.         }    
  211.     }  
  212.       
  213.   
  214.     int fb_fd = open("/dev/fb0",O_RDWR);  
  215.     if(fb_fd == -1)  
  216.     {  
  217.         printf("open fail..\n");  
  218.         return -1;  
  219.     }  
  220.   
  221.   
  222.     ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);  
  223.     ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);  
  224.   
  225.     long screensize = vinfo.yres_virtual * finfo.line_length;  
  226.     FILE *fp = popen("bash ./test.sh","r");   
  227.     pclose(fp);  
  228.   
  229.     //bmp   
  230.     if( output_file && type_file )  
  231.     {  
  232.         if( !strcmp(type,"bmp"))      
  233.         {  
  234.             image_bmp(filename);  
  235.         }else if( !strcmp(type,"png"))  
  236.         {  
  237.             printf("png type = %s\n",type);  
  238.         }  
  239.         else  
  240.         {  
  241.             printf("unkown\n");  
  242.         }  
  243.       
  244.     }     
  245.     else  
  246.     {  
  247.         usage();return 2;  
  248.     }  
  249.   
  250.     close(fb_fd);  
  251.   
  252.     return 0;  
  253. }  


[cpp]  view plain  copy
  1. #include <linux/fb.h>  
  2. #include <stdio.h>  
  3. #include <stdint.h>   
  4. #include <fcntl.h>  
  5. #include <sys/mman.h>  
  6. #include <sys/ioctl.h>   
  7. #include <getopt.h>  
  8. #include <strings.h>  
  9. #include <unistd.h>  
  10. typedef unsigned short WORD;  
  11. typedef unsigned int DWORD;  
  12. typedef unsigned long LONG;  
  13.   
  14. typedef struct tagBITMAPFILEHEADER {  
  15.     WORD bfType;  
  16.     DWORD bfSize;  
  17.     WORD bfReserved1;  
  18.     WORD bfReserved2;  
  19.     DWORD bfOffBits;   
  20. } __attribute__((packed)) BITMAPFILEHEADER;  
  21.   
  22.   
  23. typedef struct tagBITMAPINFOHEADER  
  24. {  
  25.     DWORD biSize; /*info header size in bytes*/  
  26.     DWORD biWidth; /*widht of image*/  
  27.     DWORD biHeight;/*height of image*/  
  28.     WORD biPlanes;/*number of colour planes*/   
  29.     WORD biBitCount;/*bits per pixel*/  
  30.     DWORD biCompression;/*compression type*/  
  31.     DWORD biSizeImage;/*image size meter*/  
  32.     DWORD biXPelsPerMeter;/*pixels per meter*/  
  33.     DWORD biYPelsPerMeter;/*pexels per meter*/  
  34.     DWORD biClrUsed;/*number of colour*/  
  35.     DWORD biClrImportant;/*important colour*/  
  36. } __attribute__((packed)) BITMAPINFOHEADER;  
  37.   
  38. int output_file;  
  39. int type_file;  
  40.   
  41. struct fb_fix_screeninfo finfo;  
  42. struct fb_var_screeninfo vinfo;  
  43.   
  44. static const struct option long_options[]=    
  45. {    
  46.      {"output",1,NULL,'o'},    
  47.      {"t",1,NULL,'t'},      
  48.      {NULL,0,NULL,0}    
  49. };   
  50.   
  51. static void usage(void)    
  52. {    
  53.     fprintf(stderr,    
  54.             "imax6 [option]...\n"    
  55.             "  -o|--output               Output the filename.\n"    
  56.             "  -t|--type               Output the type of thefilename.\n"  
  57.             "  -h|--help               help information.\n"  
  58.            );    
  59. };  
  60.   
  61.   
  62. static void image_bmp( const char *filename)  
  63. {  
  64.     printf("starting bmp..\n");  
  65.     char tmpbufilename[126] = {0};  
  66.     if( NULL != filename)  
  67.     {  
  68.         strcpy(tmpbufilename, filename);                  
  69.         strcat(tmpbufilename,".bmp");  
  70.     }else  
  71.     {  
  72.         strcpy(tmpbufilename,"screen.bmp");  
  73.     }  
  74.       
  75.     FILE *fp;  
  76.     BITMAPFILEHEADER    bmfh;  
  77.         BITMAPINFOHEADER    bmih;  
  78.   
  79.         ((unsigned char *)&bmfh.bfType)[0] = 'B';  
  80.         ((unsigned char *)&bmfh.bfType)[1] = 'M';  
  81.   
  82.         bmfh.bfSize =  sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + vinfo.yres * vinfo.xres * 4;  
  83.         bmfh.bfReserved1 = 0;  
  84.         bmfh.bfReserved2 = 0;  
  85.         bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  86.   
  87.         bmih.biSize = sizeof(BITMAPINFOHEADER);  
  88.   
  89.         bmih.biWidth = vinfo.xres;  
  90.         bmih.biHeight = vinfo.yres;  
  91.         bmih.biPlanes = 1;  
  92.         bmih.biBitCount = 32;  
  93.         bmih.biCompression = 0;  
  94.         bmih.biSizeImage = 0; /*说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0*/  
  95.         bmih.biXPelsPerMeter = 0; /*缺省值*/  
  96.         bmih.biYPelsPerMeter = 0;  
  97.         bmih.biClrUsed = 0; /*说明位图实际使用的调色板索引数,0:使用所有的调色板索引*/  
  98.         bmih.biClrImportant = 0; /*说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要*/  
  99.   
  100.     printf("tmpbufilename = %s\n",tmpbufilename);  
  101.   
  102.         FILE* image_file = fopen(tmpbufilename,"a");  
  103.     if( NULL == image_file)  
  104.     {  
  105.         printf("image fopen fail\n");  
  106.     }  
  107.   
  108.         fwrite(&bmfh, sizeof(BITMAPFILEHEADER),1,image_file);  
  109.         fwrite(&bmih, sizeof(BITMAPINFOHEADER),1,image_file);  
  110.   
  111.         FILE *raw_file = fopen( "test.raw","rb");  
  112.     if( NULL == raw_file)     
  113.     {  
  114.         printf("rawfile fopen fail..\n");  
  115.     }  
  116.       
  117.       
  118.     /* 
  119.     fgetc是一种计算机语言中的函数。意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。格式:int fgetc(FILE *stream); 
  120.     */  
  121.      
  122.         //int ch = fgetc(raw_file);  
  123.     int ch = getc(raw_file);  
  124.       
  125.     /* 
  126.  
  127.     for(y = 0; y < vinfo.yres; y+) 
  128.     {   
  129.         for(x = 0; x < vinfo.xres; x++)   
  130.         {   
  131.             long location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y + vinfo.yoffset) * finfo.line_length;              
  132.             write(image_file, fbp + location, 4);   
  133.         }   
  134.     }    
  135.     */  
  136.     int x, y;  
  137.     for( y = vinfo.yres - 1; y >= 0; y--)  
  138.     {  
  139.         for(x = 0; x < vinfo.xres; x++)  
  140.         {  
  141.             /*字节数*/  
  142.             long location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y + vinfo.yoffset) * finfo.line_length;  
  143.             fseek(raw_file, location, SEEK_SET);  
  144.             ch = fgetc(raw_file);  
  145.             fputc(ch,image_file);  
  146.   
  147.             ch = fgetc(raw_file);  
  148.             fputc(ch,image_file);  
  149.   
  150.             ch = fgetc(raw_file);  
  151.             fputc(ch,image_file);  
  152.   
  153.             ch = fgetc(raw_file);  
  154.             fputc(ch,image_file);   
  155.         }  
  156.     }  
  157.     /* 
  158.     while( ch != EOF) 
  159.         { 
  160.         ch = fgetc(raw_file); 
  161.                 fputc(ch,image_file); 
  162.          
  163.         ch = fgetc(raw_file); 
  164.                 fputc(ch,image_file); 
  165.  
  166.         ch = fgetc(raw_file); 
  167.                 fputc(ch,image_file); 
  168.  
  169.         ch = fgetc(raw_file); 
  170.                 fputc(ch,image_file);                 
  171.         }*/  
  172.   
  173.         fp = popen("rm ./test.raw","r");  
  174.         pclose(fp);  
  175.   
  176.     fclose(raw_file);  
  177.     fclose(image_file);  
  178.     printf("ending bmp\n");  
  179. }  
  180.   
  181. int main(int argc, char **argv)  
  182. {  
  183.     int opt = 0;  
  184.     int options_index = 0;  
  185.     char *tmp = NULL;  
  186.     char filename[126] = {0};  
  187.     char type[126] = {0};  
  188.   
  189.     if(argc == 1)  
  190.     {  
  191.         usage();  
  192.         return 2;     
  193.     }  
  194.     /* 解析命令行参数*/  
  195.     while((opt=getopt_long(argc,argv,"o:t:h?",long_options,&options_index))!=EOF )    
  196.     {    
  197.         switch(opt)    
  198.         {      
  199.             case 'o':   
  200.                 output_file=1;  
  201.                 sprintf(filename,"%s",optarg);  
  202.                 break;    
  203.             case 't':   
  204.                 type_file=1;  
  205.                 sprintf(type,"%s",optarg);  
  206.                 break;     
  207.             case 'h':    
  208.             case '?':   
  209.                 usage();return 2;break;    
  210.         }    
  211.     }  
  212.       
  213.   
  214.     int fb_fd = open("/dev/fb0",O_RDWR);  
  215.     if(fb_fd == -1)  
  216.     {  
  217.         printf("open fail..\n");  
  218.         return -1;  
  219.     }  
  220.   
  221.   
  222.     ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);  
  223.     ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);  
  224.   
  225.     long screensize = vinfo.yres_virtual * finfo.line_length;  
  226.     FILE *fp = popen("bash ./test.sh","r");   
  227.     pclose(fp);  
  228.   
  229.     //bmp   
  230.     if( output_file && type_file )  
  231.     {  
  232.         if( !strcmp(type,"bmp"))      
  233.         {  
  234.             image_bmp(filename);  
  235.         }else if( !strcmp(type,"png"))  
  236.         {  
  237.             printf("png type = %s\n",type);  
  238.         }  
  239.         else  
  240.         {  
  241.             printf("unkown\n");  
  242.         }  
  243.       
  244.     }     
  245.     else  
  246.     {  
  247.         usage();return 2;  
  248.     }  
  249.   
  250.     close(fb_fd);  
  251.   
  252.     return 0;  
  253. }  

猜你喜欢

转载自blog.csdn.net/qinrenzhi/article/details/80677899