Linux C語言解析.bmp格式圖片並顯示漢字


bmp.h 文件

 1 #ifndef __BMP_H__  2 #define __BMP_H__
 3  
 4  
 5 #include <unistd.h>
 6 #include <stdio.h>  
 7 #include <stdlib.h>    
 8 #include <fcntl.h>
 9 #include <string.h>
10 #include <linux/fb.h>
11 #include <sys/mman.h>
12 #include <sys/ioctl.h>
13 #include <arpa/inet.h>
14  
15  
16  //文件頭
17 typedef struct  
18 { 19     unsigned char    bfType[2];                   //文件類型
20     unsigned long   bfSize;                       //位圖大小
21     unsigned short  bfReserved1;                 //位0 
22     unsigned short  bfReserved2;                 //位0
23     unsigned long   bfOffBits;                  //到數據偏移量
24 } __attribute__((packed)) BitMapFileHeader; 25   
26   
27 //信息頭
28 typedef struct  
29 { 30     unsigned long   biSize;                       // BitMapFileHeader 字節數
31     long               biWidth;                       //位圖寬度 
32     long               biHeight;                     //位圖高度,正位正向,反之為倒圖 
33     unsigned short  biPlanes;                     //為目標設備說明位面數,其值將總是被設為1
34     unsigned short  biBitCount;                   //說明比特數/象素,為1、4、8、16、24、或32。 
35     unsigned long   biCompression;               //圖象數據壓縮的類型沒有壓縮的類型:BI_RGB 
36     unsigned long   biSizeImage;                  //說明圖象的大小,以字節為單位 
37     long               biXPelsPerMeter;             //說明水平分辨率 
38     long               biYPelsPerMeter;             //說明垂直分辨率 
39     unsigned long   biClrUsed;                    //說明位圖實際使用的彩色表中的顏色索引數
40     unsigned long   biClrImportant;                 //對圖象顯示有重要影響的索引數,0都重要。 
41 } __attribute__((packed)) BitMapInfoHeader; 42   
43   
44 //位圖顏色分量
45 typedef struct   
46 { 47     unsigned char Blue;                         //該顏色的藍色分量 
48     unsigned char Green;                         //該顏色的綠色分量 
49     unsigned char Red;                             //該顏色的紅色分量 
50     unsigned char Reserved;                     //保留值 
51 } __attribute__((packed)) RgbQuad; 52 
53 
54 
55 typedef struct DealInfo 56 { 57     unsigned char tmp; 58     unsigned char hum; 59     unsigned char light; 60     unsigned char fan; 61     unsigned char buzz; 62 }DealInfo; 63 
64 typedef struct QNode 65 { 66  DealInfo buf; 67     struct QNode *pNext; 68 }QNode; 69 
70 
71 
72 void plan(); 73 int show_photo(const char *fbp, struct fb_var_screeninfo *scrinfo);        //顯示圖片
74 
75 
76  
77 #endif  //__BMP_H__

bmp.c 文件

 1 #include "bmp.h"
 2 #include "word.h"
 3 
 4 
 5 extern char photo_name[20];  6 extern QNode heard;  7 
 8 
 9 //漢字字模
 10 unsigned char word[WORD_DATA_HEIGTH][WORD_DATA_WIDTH] = {  11 
 12 0x08,0x40,0x08,0x40,0x0B,0xFC,0x10,0x40,0x10,0x40,0x30,0x40,0x3F,0xFE,0x50,0x00,  13 0x90,0x40,0x10,0x40,0x13,0xFC,0x10,0x40,0x10,0x40,0x10,0x40,0x1F,0xFE,0x10,0x00,  14 
 15 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x80,0x02,0x80,  16 0x04,0x40,0x04,0x40,0x08,0x20,0x08,0x20,0x10,0x10,0x20,0x08,0x40,0x04,0x80,0x02,  17     
 18 0x08,0x20,0x04,0x40,0x7F,0xFC,0x01,0x00,0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,  19 0xFF,0xFE,0x01,0x00,0x01,0x00,0x7F,0xFC,0x02,0x80,0x04,0x40,0x18,0x30,0xE0,0x0E,  20     
 21 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x7C,0xFE,0x44,0x22,0x44,0x22,0x44,0x22,0x44,  22 0x42,0x44,0x24,0x44,0x14,0x44,0x08,0x44,0x14,0x44,0x22,0x7C,0x42,0x44,0x80,0x00,  23 
 24 0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x4F,0xE4,0x49,0x24,0x49,0x24,0x4F,0xE4,  25 0x49,0x24,0x49,0x24,0x49,0x24,0x4F,0xE4,0x40,0x04,0x40,0x04,0x7F,0xFC,0x00,0x04,  26 
 27 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  28 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  29 
 30 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,  31 0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x00,0x08,0x00,0x00,  32 
 33 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x08,0x01,0x08,0x7D,0x90,0x05,0xA0,0x09,0x40,  34 0x09,0x40,0x11,0x20,0x11,0x10,0x21,0x08,0x41,0x06,0x81,0x00,0x05,0x00,0x02,0x00,  35 
 36 0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x4F,0xE4,0x49,0x24,0x49,0x24,0x4F,0xE4,  37 0x49,0x24,0x49,0x24,0x49,0x24,0x4F,0xE4,0x40,0x04,0x40,0x04,0x7F,0xFC,0x00,0x04,  38 
 39 0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x40,0x3E,0x40,0x22,0x60,0x42,0x50,0x42,0x48,  40 0xA4,0x44,0x14,0x44,0x08,0x40,0x08,0x40,0x10,0x40,0x20,0x40,0x40,0x40,0x80,0x40,  41 
 42 0x00,0x00,0x20,0x80,0x13,0x3C,0x12,0x24,0x02,0x24,0x02,0x24,0xF2,0x24,0x12,0x24,  43 0x12,0x24,0x12,0xB4,0x13,0x28,0x12,0x20,0x10,0x20,0x28,0x20,0x47,0xFE,0x00,0x00
 44 
 45 };  46 
 47 
 48 
 49 
 50 void plan(void)  51 {  52     //映射內存地址,屏幕信息
 53     char *fbp = NULL;  54     struct fb_var_screeninfo scrinfo;  55     
 56     
 57     //設備文件的操作
 58     int devfb = open("/dev/fb0", O_RDWR);  59     if(!devfb)  60  {  61         printf("devfb open error!\r\n");  62         exit(1);  63  }  64     
 65     //屏幕信息
 66     if(ioctl(devfb, FBIOGET_VSCREENINFO, &scrinfo))  67  {  68         printf("get screen infomation error!\r\n");  69         exit(2);  70  }  71     //設置參數(圖片大小為1280*168)
 72     scrinfo.xres = 1280;  73     scrinfo.yres = 768;  74     
 75     if(ioctl(devfb, FBIOPUT_VSCREENINFO, &scrinfo))  76  {  77         printf("set screen infomation error!\r\n");  78         exit(2);  79  }  80 
 81     
 82     
 83     //內存映射
 84     unsigned long screensize = scrinfo.xres_virtual * scrinfo.yres_virtual * scrinfo.bits_per_pixel / 8;  85     fbp = (char *)mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, devfb, 0);  86     if(-1 == (int)fbp)  87  {  88         printf("mmap error!\r\n");  89         exit(3);  90  }  91     
 92     //字形處理和視頻顯示  93     //update_word(&heard);
 94     show_photo(fbp, &scrinfo);  95     
 96     //結束
 97  munmap(fbp, screensize);  98  close(devfb);  99 
100     return ; 101 } 102 
103 
104 
105 
106 int show_photo(const char *fbp, struct fb_var_screeninfo *scrinfo) 107 { 108     if(NULL == fbp || NULL == scrinfo) 109         return -1; 110     
111     
112     int xres =  scrinfo->xres_virtual; 113     int bits_per_pixel = scrinfo->bits_per_pixel; 114  BitMapFileHeader FileHead; 115  BitMapInfoHeader InfoHead; 116  RgbQuad rgb; 117     unsigned long location = 0; 118 
119     //打開.bmp文件
120     FILE *fb = fopen(photo_name, "rb"); 121     if (fb == NULL) 122  { 123         printf("fopen bmp error\r\n"); 124         return -1; 125  } 126     
127     //讀文件頭,並判斷是否為.bmp文件
128     if (1 != fread( &FileHead, sizeof(BitMapFileHeader),1, fb)) 129  { 130         printf("read BitMapFileHeader error!\n"); 131  fclose(fb); 132         return -1; 133  } 134     if (memcmp(FileHead.bfType, "BM", 2) != 0) 135  { 136         printf("it's not a BMP file\n"); 137  fclose(fb); 138         return -1; 139  } 140     
141     //獲取.bmp文件信息
142     if (1 != fread( (char *)&InfoHead, sizeof(BitMapInfoHeader),1, fb)) 143  { 144         printf("read BitMapInfoHeader error!\n"); 145  fclose(fb); 146         return -1; 147  } 148     
149     //移動至數據段,准備讀數據
150  fseek(fb, FileHead.bfOffBits, SEEK_SET); 151 
152     
153     //圖片行,列,像素信息
154     int line_x = 0, line_y = 0; 155     unsigned long tmp = 0; 156     
157     
158     int len = InfoHead.biBitCount / 8;            //原圖像素點所占字節數,24/8=3
159     int bits_len = bits_per_pixel / 8;            //屏幕像素點所占字節數,32/8=4 160     
161     
162     //右上角文字顯示區相關信息
163     int word_line_y = WORD_DATA_HEIGTH - 1;        //三行文字最底端的行 
164     int word_line_x;                            //三行文字最左端的列
165     int k;                                        //字模移動位數
166     unsigned char data = 0, one = 0; 167 
168     while(!feof(fb)) 169  { 170         tmp = 0; 171         rgb.Reserved = 0xFF; 172         
173         //對應的內存相對映射首地址的偏移量
174         location = line_x * bits_len + (InfoHead.biHeight - 1 - line_y ) * xres * bits_len; 175         
176         tmp = rgb.Reserved << 24 | rgb.Red << 16 | rgb.Green << 8 | rgb.Blue; 177     
178     
179         //文字顯示區
180         if(line_x > WORD_WIDTH && line_x < InfoHead.biWidth - 10 && 
181             line_y > WORD_HEIGTH && line_y < InfoHead.biHeight - 10 && word_line_y >= 0) 182  { 183             tmp = 0; 184             
185             
186             for(word_line_x = 0; word_line_x < WORD_DATA_WIDTH; word_line_x++) 187  { 188                 
189                 //讀字模
190                 data = word[word_line_y][word_line_x]; 191                 
192                 one = 0x80; 193                 
194                 for(k = 0; k < BIT_WIDTH; k++) 195  { 196                     
197                     fread((char *)&rgb, 1, len, fb); 198                     
199                     //確定有效位
200                     if(data & one) 201                         tmp = 0;    //黑色字體
202             
203                     else
204                         tmp = rgb.Reserved << 24 | rgb.Red << 16 | rgb.Green << 8 | rgb.Blue; 205                 
206                     
207                     location = line_x * bits_len + (InfoHead.biHeight - 1 - line_y ) * xres * bits_len; 208                     *((unsigned long *)(fbp + location)) = tmp; 209                     
210                     one >>= 1; 211                 
212                     //自增列
213                     line_x++; 214                     if (line_x == InfoHead.biWidth ) 215  { 216                         line_x = 0; 217                         
218                         //自增行
219                         line_y++; 220                         if(line_y == InfoHead.biHeight) 221                             break; 222  } 223  } 224  } 225             
226             //字模從下往上讀和顯示
227             word_line_y--; 228             continue; 229         
230  } 231 
232         //讀.bmp文件
233         if (len != fread((char *)&rgb, 1, len, fb)) 234             break; 235         
236         
237         //顯示非文字區的圖片
238         *((unsigned long *)(fbp + location)) = tmp; 239             
240         //自增列 
241         line_x++; 242         if (line_x == InfoHead.biWidth ) 243  { 244             line_x = 0; 245             
246             //自增行
247             line_y++; 248             if(line_y == InfoHead.biHeight) 249                 break; 250  } 251  } 252 
253     
254  fclose(fb); 255 
256     return 0; 257 }

main函數

1 int main() 2 { 3 
4  plan(); 5 
6     return 0; 7 }

 

效果圖(我不是給這游戲打廣告)

說明:1.圖片是24位或32位bmp圖

     2.屏幕是32位屏幕

     3.不同的設備,可能設備文件不同

     4.需要在root用戶下執行

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM