用C语言解析BMP文件的结构

http://blog.sina.com.cn/s/blog_6612e1860100hckw.html

昨天得到嵌入式小组的一个测试题:用c语言打开bmp格式的图片。C语言是学过了,但转载这篇文章对bmp文件不甚了解,为此转载这篇文章来了解一下。

 

用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 nStrLen; 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 nStrLen; 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; 
  {
  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; 
  {
  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;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值