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用戶下執行