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用户下执行