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