博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C语言读写BMP linux 平台

Posted on 2009-06-23 11:08  方恨少  阅读(1540)  评论(0)    收藏  举报
#include<stdio.h>
#include<malloc.h>
typedef int bool;
typedef unsigned long DWORD;
#define true   1;
#define false  0;
#define WIDTHBYTES(i) ((i+31)/32*4)  
typedef   struct  
  {  
      unsigned short     bfType;                         /*   文件类型,   必须为   "BM"(0x4D42) */  
      unsigned long   bfSize;                         /*   文件的大小(字节)   */  
      unsigned short     bfReserved1;               /*   保留,   必须为   0   */  
      unsigned short     bfReserved2;               /*   保留,   必须为   0   */  
      unsigned long   bfoffBits;                   /*   位图阵列相对于文件头的偏移量(字节)   */  
  }  BITMAPFILEHEADER;               /*   文件头结构   */  
   
  typedef   struct  
  {  
     unsigned long   biSize;                         /*   size   of   BITMAPINFOHEADER   */  
     unsigned long   biWidth;                       /*   位图宽度(像素)   */  
     unsigned long   biHeight;                     /*   位图高度(像素)   */  
     unsigned short  biPlanes;                     /*   目标设备的位平面数,   必须置为1   */  
     unsigned short  biBitCount;                 /*   每个像素的位数,   1,4,8或24   */  
     unsigned long   biCompress;                 /*   位图阵列的压缩方法,0=不压缩   */  
     unsigned long   biSizeImage;               /*   图像大小(字节)   */  
     unsigned long   biXPelsPerMeter;       /*   目标设备水平每米像素个数   */  
     unsigned long   biYPelsPerMeter;       /*   目标设备垂直每米像素个数   */  
     unsigned long   biClrUsed;                   /*   位图实际使用的颜色表的颜色数   */  
     unsigned long   biClrImportant;         /*   重要颜色索引的个数   */  
  }   BITMAPINFOHEADER;               /*   位图信息头结构   */  

  FILE   *in;
  FILE  *out;  
  unsigned   char   b1;  
  BITMAPFILEHEADER     bfile;  
  BITMAPINFOHEADER     binfo;
//RGBQUAD     *bquad;  
  bool  truecolor;
  char   infilename[100],   outfilename[100]="done_bmp.bmp";

  unsigned long LineByte,ImgSize;    
  unsigned long NumColors;    
 

  char* bitmapdata = NULL;
  bool GetBitmapData();
  void   init();   
int main()
{
    printf("%d,%d",sizeof(BITMAPFILEHEADER),sizeof(BITMAPINFOHEADER));
    init();  
    GetBitmapData();
//      getType();  
//    if   (truecolor)   change();  
  //else  change2();  
   
      fclose(in);  
      fclose(out);  
    return 0;
}
void   init()  
{
    int i = 0;
    printf("input   the   BMP   file   name:");  
    scanf("%s",   infilename);  
    in   =   fopen(infilename,   "rb");
    printf("open sucessful\n");
    if   (in)  
    {  
//        fread(&bfile,   sizeof(bfile),   1,   in);  
//        fread(&binfo,   sizeof(binfo),   1,   in);
        fread(&bfile.bfType,   sizeof(bfile.bfType),   1,   in);  
        fread(&bfile.bfSize,   sizeof(bfile.bfSize),   1,   in);
        fread(&bfile.bfReserved1,   sizeof(bfile.bfReserved1),   1,   in);
        fread(&bfile.bfReserved2,   sizeof(bfile.bfReserved2),   1,   in);
        fread(&bfile.bfoffBits,   sizeof(bfile.bfoffBits),   1,   in);
        fread(&binfo.biSize,   sizeof(binfo.biSize),   1,   in);
        fread(&binfo. biWidth,   sizeof(binfo. biWidth),   1,   in);
        fread(&binfo.biHeight,   sizeof(binfo.biHeight),   1,   in);
        fread(&binfo.biPlanes,   sizeof(binfo.biPlanes),   1,   in);
        fread(&binfo.biBitCount,   sizeof(binfo.biBitCount),   1,   in);
        fread(&binfo.biCompress,   sizeof(binfo.biCompress),   1,   in);
        fread(&binfo.biSizeImage,   sizeof(binfo.biSizeImage),   1,   in);
        fread(&binfo.biXPelsPerMeter,   sizeof(binfo.biXPelsPerMeter),   1,   in);
        fread(&binfo.biYPelsPerMeter,   sizeof(binfo.biYPelsPerMeter),   1,   in);
        fread(&binfo.biClrUsed,   sizeof(binfo.biClrUsed),   1,   in);
        fread(&binfo.biClrImportant,   sizeof(binfo.biClrImportant),   1,   in);

printf("%ld\n",binfo.biSize);
printf("%ld\n",binfo.biWidth);
printf("%ld\n",binfo.biHeight);
 printf("%d\n",binfo.biPlanes);
printf("%d\n",binfo.biBitCount);
printf("%d\n",binfo.biCompress);
printf("%ld\n",binfo.biSizeImage);
printf("%ld\n",binfo.biXPelsPerMeter);
printf("%ld\n",binfo.biYPelsPerMeter);
printf("%ld\n",binfo.biClrUsed);
        printf("outfilename:\n");
        out   =   fopen(outfilename,   "wb");
          if(out)
        {
            printf("outfile success\n");
            //printf("%d",sizeof(bfile));
             fwrite(&bfile.bfType,   sizeof(bfile.bfType),   1,   out);  
            fwrite(&bfile.bfSize,   sizeof(bfile.bfSize),   1,   out);
            fwrite(&bfile.bfReserved1,   sizeof(bfile.bfReserved1),   1,   out);
            fwrite(&bfile.bfReserved2,   sizeof(bfile.bfReserved2),   1,   out);
            fwrite(&bfile.bfoffBits,   sizeof(bfile.bfoffBits),   1,  out);
            fwrite(&binfo.biSize,   sizeof(binfo.biSize),   1,   out);
            fwrite(&binfo. biWidth,   sizeof(binfo. biWidth),   1,   out);
            fwrite(&binfo.biHeight,   sizeof(binfo.biHeight),   1,   out);
            fwrite(&binfo.biPlanes,   sizeof(binfo.biPlanes),   1,   out);
            fwrite(&binfo.biBitCount,   sizeof(binfo.biBitCount),   1,   out);
            fwrite(&binfo.biCompress,   sizeof(binfo.biCompress),   1,   out);
            fwrite(&binfo.biSizeImage,   sizeof(binfo.biSizeImage),   1,  out);
            fwrite(&binfo.biXPelsPerMeter,   sizeof(binfo.biXPelsPerMeter),   1,  out);
            fwrite(&binfo.biYPelsPerMeter,   sizeof(binfo.biYPelsPerMeter),   1,  out);
            fwrite(&binfo.biClrUsed,   sizeof(binfo.biClrUsed),   1,  out);
            fwrite(&binfo.biClrImportant,   sizeof(binfo.biClrImportant),   1,  out);  
            //printf("bfile written\n");
              //fwrite(&binfo,   sizeof(binfo),   1,   out);  
            printf("end\n");
        }
        else
        {
            printf("outfile failed\n");
        }

    }  
    else  
    {  
        printf("Open   File   Error!   No   such   file!\n");  
        exit(0);  
    }  
  }  
bool GetBitmapData()
{
    int i = 0;
    int j = 0;
    unsigned char Imgdata[binfo.biHeight][binfo.biWidth*3];
    printf("ready\n");
    //fread(&binfo,   sizeof(binfo),   1,   in);  

    LineByte=(unsigned long)((binfo.biWidth*binfo.biBitCount + 31)/32 *4); //计算位图的实际宽度并确保它为32的倍数   
    printf("%ld\n",LineByte);


      ImgSize=(unsigned long)LineByte*binfo.biHeight;               
      printf("%ld",ImgSize);
      if (binfo.biClrUsed != 0 )    
          NumColors=(DWORD)binfo.biClrUsed;    
    else    
          switch (binfo.biBitCount)    
            {      
                case 1:NumColors=2;break;    
                case 4:NumColors=16;break;    
               case 8:NumColors=256;break;    
               case 24:NumColors=0;break;    
            }    
    printf("switch end\n");
    //Imgdata=(unsigned char**)malloc(binfo.biHeight); //声明一个指针数组   
    printf("malloc success 1\n");
    if(binfo.biBitCount==24)
    {   
          fseek(in, 4, SEEK_CUR);//sizeof(RGBQUAD)
        printf("seek finished\n");  
 //         for( i=(binfo.biHeight)-1;i>=0;i--)    
//               Imgdata[i]=(unsigned char*)malloc(binfo.biWidth*3);//每个数组元素也是一个指针数组   
          printf("malloc success 2");
            for ( i=(binfo.biHeight)-1;i>=0;i--)    
                for(j=0;j<binfo.biWidth*3;j++)    
                    fread(&Imgdata[i][j],1,1,in);//每次只读取一个1字节,存入数组    
    }
    printf("read finished\n");


    for (i=(binfo.biHeight)-1 ;i>=0;i--)  
    {  
          for (j=0 ;j<binfo.biWidth*3;j++)
        {   
                //Imgdata[i][j] = 255 - Imgdata[i][j];  
            //printf("%d,",Imgdata[i][j]);
                fwrite(&Imgdata[i][j],1,1,out);    
           }   
        printf("\n");
    }

}