bmp文件的结构比较简单,主要包括文件头,BMP信息头,BMP数据内容。文件头BITMAPFILEHEADER结构为: Windows GDI提供了
typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, *PBITMAPFILEHEADER; BMP信息头BITMAPINFO结构为: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; typedef struct tagBITMAPCOREINFO { BITMAPCOREHEADER bmciHeader; RGBTRIPLE bmciColors[1]; } BITMAPCOREINFO, FAR *LPBITMAPCOREINFO, *PBITMAPCOREINFO; #include typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; | 有一次,一个朋友给了一套BMP文字的图片,想把BMP转化为字库,需要去掉BMP的头和BMP信息,只取数据部分,并存为数组,就根据BMP结构,写了如下一个小程序,主要包括文件读写,文件查找等:
#include #include #include #include BITMAPFILEHEADER file_head; BITMAPINFO fileinfo; //把彩色的图转为黑白色,输入源文件名字和转出的文件名字 #define FONT_WIDTH_1 (28) #define FONT_WIDTH_2 (22) char * getfilename(char * filename) { char strResult[128]={0}; //保存结果 char *temp, *ret; temp = filename; int nStrLen = strlen(filename); //原始字符串长度 for(int i = nStrLen; i > 0; i--) //倒查,每个字符和反斜杠对比 { if (filename[i] == '\\') //如果当前字符是反斜杠 { //复制倒数第一个斜杠后的数据,并去掉.bmp strncpy(strResult, (char *)(temp+i+1), nStrLen-i-1-4); break; } else { //复制字符串,去掉.bmp if (i = 1) { strncpy(strResult, (char *)temp, nStrLen-4); break; } } } ret = strResult; return (ret); } #if 1 char * getfilepath(char * filename) { char strResult[128] = {0}; //保存结果 char *temp, *ret; temp = filename; int nStrLen = strlen(filename); //原始字符串长度 for(int i = nStrLen; i > 0; i--) //倒查,每个字符和斜杠对比 { if (filename[i] == '\\') //如果当前字符是斜杠 { //复制路径,包括斜杠 strncpy(strResult, (char *)temp, i+1); break; } } ret = strResult; return (ret); } #endif int colorbmp2bwbmp(char * f_in, char * f_out) { int infileLen; //文件长度 int n=0; //n 字节计数器 unsigned char c,c_in; //C_in文件字节,C转化 FILE *fh_in; FILE *fh_out; assert((f_in != NULL) && (f_out != NULL)); fh_in=fopen(f_in,"rb"); if (NULL==fh_in) { printf("open read file error!!"); return 1; } fseek(fh_in,0,SEEK_END); infileLen=ftell(fh_in); fseek(fh_in,0,SEEK_SET); if (sizeof(file_head)!=fread(&file_head,1,sizeof(file_head),fh_in)) { printf("read bmp file error!!"); fclose(fh_in); return 1; } if (file_head.bfType!=0x4d42) { printf("bmp file error!!"); fclose(fh_in); return 1; } fseek(fh_in,0,SEEK_SET); fh_out=fopen(f_out,"wb"); if (NULL==fh_out) { printf("open write file error!!"); return 1; } while((int)file_head.bfOffBits--) { c_in=getc(fh_in); c=c_in; putc(c,fh_out); } while (n<(infileLen-(int)file_head.bfOffBits)) { c_in=getc(fh_in); c=c_in; if (c>0x7f) { c =0xff; } else { c = 0x00; } putc(c,fh_out); n++; } fclose(fh_in); fclose(fh_out); return 0; } //byte转为BIT void ByteToBit(char *Out, const char *In, unsigned char bits) { unsigned char i; for(i=0; i { Out[i] = (In[i/8]>>(i%8)) & 1; } } //BIT转为byte void BitToByte(char * Out, const char *In, unsigned bits) { unsigned char i; memset(Out, 0, (bits+7)/8); for(i=0; i { Out[i/8] |= In[i]<<(i%8); } } //把位图转为文件,输入bmp文件名和头文件名 int bmp2headfile(char * bmpfile, char * headfile) { int infileLen; //文件长度 int n=0,num=1; //n 字节计数器, NUM换行指示 unsigned char c, c_in; //C_in文件字节,C转化 FILE *fh_in; FILE *fh_out; char com[256]={0}; char ch[2]={0}; long wid, hig; assert((bmpfile != NULL) && (headfile != NULL)); fh_in=fopen(bmpfile,"rb"); if (NULL==fh_in) { printf("open read file error!!"); return 1; } fseek(fh_in,0,SEEK_END); infileLen=ftell(fh_in); fseek(fh_in,0,SEEK_SET); if (sizeof(file_head)!=fread(&file_head,1,sizeof(file_head),fh_in)) { printf("read bmp file error!!"); fclose(fh_in); return 1; } if (sizeof(fileinfo)!=fread(&fileinfo,1,sizeof(fileinfo),fh_in)) { printf("read bmp file error!!"); fclose(fh_in); return 1; } if (file_head.bfType!=0x4d42) { printf("bmp file error!!"); fclose(fh_in); return 1; } fseek(fh_in,file_head.bfOffBits,SEEK_SET); fh_out=fopen(headfile,"ab"); if (NULL==fh_out) { printf("open write file error!!"); return 1; } memcpy(ch, getfilename(bmpfile), sizeof(getfilename(bmpfile))); wid = fileinfo.bmiHeader.biWidth; hig = fileinfo.bmiHeader.biHeight; sprintf(com, "", wid, hig, ch); fputs(com, fh_out); putc(0x0d,fh_out); putc('\n',fh_out); while (n<(infileLen-(int)file_head.bfOffBits)) { putc('0',fh_out); putc('X',fh_out); c_in=getc(fh_in); c=c_in; c=(c>>4)&0x0f; //获取高四个BIT的内容 if (c<0x0a) { c+=0x30; //把符号转成数字 } else { c+=0x37; //转成a到f } putc(c,fh_out); c=c_in&0x0f; //获取低四个BIT内容 if (c<0x0a) { c+=0x30; } else { c+=0x37; } putc(c,fh_out); putc(',',fh_out); n++; if (num++ % (fileinfo.bmiHeader.biWidth/8 + 1) ==0) { putc(0x0d,fh_out); putc('\n',fh_out); } } putc(0x0d,fh_out); putc('\n',fh_out); fclose(fh_in); fclose(fh_out); return 0; } int main(int argc, char* argv[]) { WIN32_FIND_DATA fd; if (argc>2) { printf("***************位图帮助***************\n"); printf("bmptofile [drive:][path][filename]"); return 1; } else if (argc == 2) { if (strchr(argv[1], '.')!=NULL) { bmp2headfile(argv[1], (char *)"font.h"); } else //if (memcmp(argv[1], "\?", sizeof(argv[1])) == 0) { printf("***************位图帮助***************\n"); printf("bmptofile [drive:][path][filename]"); return 1; } } else if (argc == 1) { HANDLE hd=::FindFirstFile((LPCTSTR)"*.bmp",&fd); //开始查找 if(hd==INVALID_HANDLE_VALUE) { printf("没有找到文件"); return 0; } bmp2headfile(fd.cFileName, (char *)"font.h"); while(FindNextFile(hd,&fd)) //继续查找 { bmp2headfile(fd.cFileName, (char *)"font.h"); } FindClose(hd);//关闭查找 } return 0; } | |