BMP读图

//bmp.h

#pragma pack (1)

typedef struct tagBITMAPFILEHEADER
{
 
   unsigned char bfType[2];
   int bfSize;
   unsigned short bfReserved1;
   unsigned short bfReserved2;
   int bfOffBits;
}BITMAPFILEHEADER;


typedef struct tagBITMAPINFOHEADER
{
   int biSize;
   int biWidth;
   int biHeight;
   unsigned short biPlanes;
   unsigned short biBitCount;
   int biCompression;
   int biSizeImage;
   int biXPelsPerMeter;
   int biYPelsPerMeter;
   int biClrUsed;
   int biClrImportant;
}BITMAPINFOHEADER;

typedef struct tagRGBQUAD
{
   unsigned char rgbBlue;
   unsigned char rgbGreen;
   unsigned char rgbRed;
   unsigned char rgbReserved;
}RGBQUAD;


//全局变量的定义
extern unsigned char *pBmpBuf;  //读入图像数据的指针
extern int bmpWidth;            //图像的宽
extern int bmpHeight;           //图像的高
extern RGBQUAD *pColorTable;    //颜色表指针
extern unsigned short biBitCount;          //图像类型,每像素位数
extern int lineByte;            //每行字节数

 

//read.c

#include "stdio.h"
#include "bmp.h"


bool bmpread(char *bmpname)
{
  
   FILE *fp=fopen(bmpname,"rb");       //二进制读方式打开bmpname文件
   FILE *ft=fopen("bmp.txt","wb");
   if(fp==0)return 0;                  //stdio.h中将NULL定义为0
   else                                //打开成功
   {
      //读文件头,并且进行文件类型判断
      BITMAPFILEHEADER fhead;
      fread(&fhead,sizeof(BITMAPFILEHEADER),1,fp);

      if(fhead.bfType[0]=='B'&&fhead.bfType[1]=='M')    //文件为bmp格式
   {
         BITMAPINFOHEADER head;                      //定义位图信息头结构变量,
         fread(&head,sizeof(BITMAPINFOHEADER),1,fp); //读取信息头进内存,存放在head中,sizeof(BITMAPINFOHEADER=40,

         //获取宽、高、每像素所占位数-可判断颜色表类型,大小、位图实际用到的颜色数
         bmpWidth=head.biWidth;
         bmpHeight=head.biHeight;
         biBitCount=head.biBitCount;

         //计算每行像素所占的字节数(必须是4的倍数)
         lineByte=((bmpWidth*biBitCount)/8+3)/4*4;


         //对不同类型的图像进行申请颜色表内存,并且读颜色表
         switch(biBitCount)
    {
          case 1: pColorTable=new RGBQUAD[2];fread(pColorTable,sizeof(RGBQUAD),2,fp);break;
          case 4: pColorTable=new RGBQUAD[16];fread(pColorTable,sizeof(RGBQUAD),16,fp);break;
          case 8: pColorTable=new RGBQUAD[256];fread(pColorTable,sizeof(RGBQUAD),256,fp);break;
          default: break;
    }
         //申请位图数据所需空间,读位图数据进内存
         pBmpBuf=new unsigned char [lineByte*bmpHeight];
         fread(pBmpBuf,1,lineByte*bmpHeight,fp);
        
         //输出位图数据,及一些重要的参数
         printf("bfType=%c%c, biBitCount=%d/n",fhead.bfType[0],fhead.bfType[1],head.biBitCount);
   printf("Width=%d, Height=%d, size=%d/n",head.biWidth,head.biHeight,fhead.bfSize);
         printf("lineByte*bmpHeight=%d/n",lineByte*bmpHeight);
       
   //输出位图数据,只能输出较小内容的图片数据
   if(fhead.bfSize<5000000)
   {
    printf("imagedate:/n");
       int i,j;
       unsigned char *p;
       p=pBmpBuf;
             for(j=0;j<bmpHeight;j++)
    {
                for(i=0;i<lineByte;i++)
    {
             printf("%d ",*p);p++;
       if(*p<15){
       fprintf(ft,"0x0000000%x/r/n",*p);
       }else{
       fprintf(ft,"0x000000%x/r/n",*p);
       }
       p++;
    }
          printf("/n");
    }
         }
         //关闭文件
         fclose(fp);
         fclose(ft);
         return 1;
   }
   else return 0;    
   }
}

 

//write.c

#include "stdio.h"
#include "bmp.h"

bool bmpwrite(char *bmpname,unsigned char *imgBuf,int Width,int Height,int biBitCount,RGBQUAD *pColorTable)
{
   //如果位图数据指针为0,则返回
 if(!imgBuf)return 0;
 else
 {
    //以二进制写的方式打开文件
    FILE *fp=fopen(bmpname,"wb");
    if(fp==0)return 0;
       else
    {
       int lineByte=(Width*biBitCount/8+3)/4*4;

       int colorTablesize=0;
       switch(biBitCount)
    {
          case 1: colorTablesize=8;break;
          case 4: colorTablesize=64;break;
          case 8: colorTablesize=1024;break;
          default: break;
    }

          //申请文件头结构变量,填写文件头信息
       BITMAPFILEHEADER fileHead;
       fileHead.bfType[0]='B';
       fileHead.bfType[1]='M';
          fileHead.bfSize=54+colorTablesize+lineByte*Height;   //fileHead.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize+lineByte*height;
       fileHead.bfReserved1=0;
       fileHead.bfReserved2=0;
       fileHead.bfOffBits=54+colorTablesize;

       //写文件头
          fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);

       //申请位图信息头结构变量,填写信息头信息
       BITMAPINFOHEADER head;
       head.biBitCount=biBitCount;
       head.biClrImportant=0;
       head.biClrUsed=0;
       head.biCompression=0;
       head.biHeight=Height;
       head.biPlanes=1;
       head.biSize=40;
       head.biSizeImage=lineByte*Height;
       head.biWidth=Width;
       head.biXPelsPerMeter=0;
       head.biYPelsPerMeter=0;

       //写位图信息头进内存
       fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);

          //写入颜色表
       switch(biBitCount)
    {
         case 1: fwrite(pColorTable,sizeof(RGBQUAD),2,fp);break;
         case 4: fwrite(pColorTable,sizeof(RGBQUAD),16,fp);break;
         case 8: fwrite(pColorTable,sizeof(RGBQUAD),256,fp);break;
         default: break;
    }

       //写入位图数据进文件
       fwrite(imgBuf,Height*lineByte,1,fp);

       //关闭文件
       fclose(fp);
       return 1;
    }
 }
}

 

//main.c

#include "stdio.h"
#include "bmp.h"

unsigned char *pBmpBuf;  //读入图像数据的指针
int bmpWidth;            //图像的宽
int bmpHeight;           //图像的高
RGBQUAD *pColorTable;    //颜色表指针
unsigned short biBitCount;          //图像类型,每像素位数
int lineByte;            //每行字节数


void main()
{
    //申明调用函数
 bool bmpread(char *bmpname);
 bool bmpwrite(char *bmpname,unsigned char *imgBuf,int Width,int Height,int biBitCount,RGBQUAD *pColorTable);
 
 //读入指定BMP文件路径
 char readPath[]="red.bmp";
 char writePath[]="bwcpy.txt";

 int a=bmpread(readPath);
 if(!a)printf("cann't read the file!");
 else
 {
    //将图像数据存盘
    int b=bmpwrite(writePath,pBmpBuf,bmpWidth,bmpHeight,biBitCount,pColorTable);

       if(!b)printf("cann't write to the file!");

    //清除缓冲区,pBmpBuf,pColorTable是全局变量,在文件读入时申请的空间
    delete []pBmpBuf;
    if(biBitCount!=24) delete []pColorTable;
  }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值