#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef unsigned short int WORD;
typedef unsigned int DWORD;
typedef int LONG;
typedef unsigned char BYTE;
/*********** *********** *********** *********** *********** *********** ***********
* definition :struct
* Description :位图文件头
*********** *********** *********** *********** *********** *********** ***********/
#pragma pack(1)/////////////////将结构体中成员按n字节对齐
typedef struct tagBITMAPFILEHEADER
{
WORD bfType;////////////////文件类型,必须为BM
DWORD bfSize;///////////////指定文件大小,以字节为单位(3-6字节,低位在前)
WORD bfReserved1;///////////文件保留字,必须为0
WORD bfReserved2;///////////文件保留字,必须为0
DWORD bfOffBits;////////////从文件头到实际位图数据的偏移字节数(11-14字节,低位在前)
}BITMAPFILEHEADER;
/*********** *********** *********** *********** *********** *********** ***********
* definition :struct
* Description :位图信息头
*********** *********** *********** *********** *********** *********** ***********/
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;///////////////本结构所占用字节数,为40。注意:实际操作中则有44,这是字节补齐的原因
LONG biWidth;///////////////位图的宽度,以像素为单位
LONG biHeight;//////////////位图的高度,以像素为单位
WORD biPlanes;//////////////目标设备的级别,必须为1
WORD biBitCount;////////////每个像素所需的位数,1(双色),4(16色),8(256色)16(高彩色),24(真彩色)或32之一
DWORD biCompression;////////位图压缩类型,0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORD biSizeImage;//////////位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位
LONG biXPelsPerMeter;///////位图水平分辨率,每米像素数
LONG biYPelsPerMeter;///////位图垂直分辨率,每米像素数
DWORD biClrUsed;////////////位图实际使用的颜色表中的颜色数,若该值为0,则使用颜色数为2的biBitCount次方
DWORD biClrImportant;///////位图显示过程中重要的颜色数,若该值为0,则所有的颜色都重要
}BITMAPINFOHEADER;
#pragma pack()//////////////////取消自定义字节方式
/*********** *********** *********** *********** *********** *********** ***********
* definition :struct
* Description :调色板
*********** *********** *********** *********** *********** *********** ***********/
typedef struct tagRGBQUAD
{
BYTE rgbBlue;///////////////蓝色的亮度(0-255)
BYTE rgbGreen;//////////////绿色的亮度(0-255)
BYTE rgbRed;////////////////红色的亮度(0-255)
BYTE rgbReserved;///////////保留,必须为0
}RGBQUAD;
/*********** *********** *********** *********** *********** *********** ***********
* Function Name :printInfo
* Description :输出文件信息
*********** *********** *********** *********** *********** *********** ***********/
void printInfo(BITMAPFILEHEADER fileHeader,BITMAPINFOHEADER infoHeader)
{
printf("\n\n\tThe information of your map:\n");
printf("\t----------------------------------------------\n");
printf("\tbfOffBits:\t%d\n",fileHeader.bfOffBits);
printf("\tbfSize:\t\t%d\n\n",fileHeader.bfSize);
printf("\tbiBitCount:\t%d\n",infoHeader.biBitCount);
printf("\tbiHeight:\t%d\n",infoHeader.biHeight);
printf("\tbiWidth:\t%d\n",infoHeader.biWidth);
printf("\tbiSize:\t\t%d\n",infoHeader.biSize);
printf("\tbiClrUsed:\t%d\n\n\n",infoHeader.biClrUsed);
}
/*********** *********** *********** *********** *********** *********** ***********
* Function Name :printInfo
* Description :输出画板信息
*********** *********** *********** *********** *********** *********** ***********/
void printPalette(RGBQUAD *rgbPalette,int sizeOfPalette)
{
int i;
printf("\tThe Palette of your map:\n");
printf("\t----------------------------------------------\n");
for(i=0;i<sizeOfPalette;i++)
{
printf("\t%d/%d:",i+1,sizeOfPalette);
printf("\trgbBlue=%d\t",(rgbPalette+i)->rgbBlue);
printf("\trgbGreen=%d\t",(rgbPalette+i)->rgbGreen);
printf("\trgbRed=%d\n",(rgbPalette+i)->rgbRed);
}
printf("\n\n\n");
}
bool ReadBmp(BITMAPFILEHEADER &fileHeader,BITMAPINFOHEADER &infoHeader,RGBQUAD *&rgbPalette/*给它去别名一起变化*/,void *img[5000],char *FileName)
{
FILE *fpIn=fopen(FileName,"rb");
int i=0,sizeOfHang=0,sizeOfPalette=0;
if(fpIn==NULL)
return false;
fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,fpIn);
fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,fpIn);
if(infoHeader.biBitCount<16)
{
sizeOfPalette=int( pow(2,infoHeader.biBitCount) );
rgbPalette=new RGBQUAD[sizeOfPalette];
fread(rgbPalette,sizeof(RGBQUAD),sizeOfPalette,fpIn);
}
if( (infoHeader.biBitCount * infoHeader.biWidth)%32==0)
sizeOfHang=(infoHeader.biBitCount * infoHeader.biWidth)/8;
else
sizeOfHang=((infoHeader.biBitCount * infoHeader.biWidth)/32+1)*4;
for(i=0;i<infoHeader.biHeight;i++)
{
img[i]=(void *) new BYTE[sizeOfHang];
fread(img[i],sizeOfHang,1,fpIn);
}
fclose(fpIn);
return true;
}
void SaveBmp(BITMAPFILEHEADER &fileHeader,BITMAPINFOHEADER &infoHeader,RGBQUAD *rgbPalette,void *img[5000],char *FileName)
{
FILE *fpOut=fopen(FileName,"wb");
int i=0,sizeOfHang=0,sizeOfPalette=0;
fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,fpOut);
fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,fpOut);
if(infoHeader.biBitCount<16)
{
sizeOfPalette=int( pow(2,infoHeader.biBitCount) );
fwrite(rgbPalette,sizeof(RGBQUAD),sizeOfPalette,fpOut);
}
if( (infoHeader.biBitCount * infoHeader.biWidth)%32==0)
sizeOfHang=(infoHeader.biBitCount * infoHeader.biWidth)/8;
else
sizeOfHang=((infoHeader.biBitCount * infoHeader.biWidth)/32+1)*4;
for(i=0;i<infoHeader.biHeight;i++)
fwrite(img[i],sizeOfHang,1,fpOut);
fclose(fpOut);
}
void main()
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
RGBQUAD *rgbPalette;//调色板
void * img[5000];
char *FileName="E:\\1.bmp";
ReadBmp(fileHeader,infoHeader,rgbPalette,img,FileName);
SaveBmp(fileHeader,infoHeader,rgbPalette,img,"E:\\2.bmp");
}