c语言读取文件系统idone位图,用C语言解析BMP文件的结构

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);

/*read bmp file head,14 BYTE*/

if (sizeof(file_head)!=fread(&file_head,1,sizeof(file_head),fh_in))

{

printf("read bmp file error!!");

fclose(fh_in);

return 1;

}

/*判断是不是BMP文件*/

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

{

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]<

}

}

//把位图转为文件,输入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);

/*读取BMP文件头*/

if (sizeof(file_head)!=fread(&file_head,1,sizeof(file_head),fh_in))

{

printf("read bmp file error!!");

fclose(fh_in);

return 1;

}

/*读取BMP文件信息*/

if (sizeof(fileinfo)!=fread(&fileinfo,1,sizeof(fileinfo),fh_in))

{

printf("read bmp file error!!");

fclose(fh_in);

return 1;

}

/*判断是不是BMP图片*/

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, "/*The size is :%dX%d. The char is : %s.*/", wid, hig, ch);

fputs(com, fh_out);

putc(0x0d,fh_out);

putc('/n',fh_out);

/*写入数据*/

while (n

{

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值