bmp位图格式有好几种,结构上稍有不同。下面只针对标准的24位位图。
一个标准的24位位图,由54字节的头,和位图数据组成。
其中头分为3部分:2字节的效验字符,12字节文件头,40字节文件信息。
- 效验字符一定为大写字母BM的ascii码。
- 文件头分为3部分:
- 前4字节是一个无符号的32位整数,表示文件大小;
- 中间4字节位保留字段,目前用途不明,一般为0;
- 后4字节位32是一个无符号的32位整数,表示位图数据的偏移量,一般为54。
- 文件信息共11个字段,其中只有两个字段为2字节, 其余均为4字节。详细见结构体定义。其一般取值见函数。
struct bmp_magic { char magic[2]; }; struct bmp_head { unsigned file_size; unsigned short creater1; unsigned short creater2; unsigned offset; }; struct bmp_info { unsigned header_size; unsigned width; unsigned height; unsigned short nplanes; unsigned short bitspp; unsigned compress_type; unsigned image_size; unsigned hres; unsigned vres; unsigned ncolors; unsigned nimpcolors; }; void write_bmp_head(FILE *fp, unsigned short w, unsigned short h) { unsigned char buffer[54]; unsigned skip = (unsigned) w * 3; while (skip % 4) ++skip; buffer[0] = 'B'; buffer[1] = 'M'; bmp_head *head = (bmp_head *) (buffer + 2); head->file_size = skip * h + 54; head->creater1 = 0; head->creater2 = 0; head->offset = 54; bmp_info *info = (bmp_info *) (buffer + 14); info->header_size = 40; info->width = w; info->height = h; info->nplanes = 1; info->bitspp = 24; info->compress_type = 0; info->image_size = skip * h; info->hres = 0; info->vres = 0; info->ncolors = 0; info->nimpcolors = 0; fwrite(buffer, 54, 1, fp); } void write_bmp_data(FILE *fp, unsigned short w, unsigned short h, unsigned *bitmap) { unsigned pad = (4 - w * 3 % 4) % 4; unsigned padding = 0; unsigned *p; bitmap += w * h; while (h > 0) { p = bitmap - w; while (p < bitmap) { fwrite(p, 3, 1, fp); ++p; } if (pad) fwrite(&padding, pad, 1, fp); bitmap -= w; --h; } } void read_bmp_data(FILE *fp, unsigned short w, unsigned short h, unsigned *bitmap) { unsigned pad = (4 - w * 3 % 4) % 4; unsigned padding = 0; unsigned *p; bitmap += w * h; while (h > 0) { p = bitmap - w; while (p < bitmap) { fread(p, 3, 1, fp); ++p; } if (pad) fread(&padding, pad, 1, fp); bitmap -= w; --h; } }