花了几个小时把BMP文件的格式内容看了一遍,写了个小程序。。。
BMP文件格式写的不错的文章:http://www.cnblogs.com/ZXYloveFR/archive/2012/08/06/2625225.html
BMP文件的格式:
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
主要代码:(功能包括:从BMP文件中读取文件头,信息头,和位图数据。。再把数据写入到我们自己定义的一个bmp文件中。)
#include<iostream>
#include <Windows.h>
using namespace std;
void main()
{
FILE* stream=fopen("D:\\3.bmp","rb");
if(stream==NULL)
{
cout<<"文件不存在"<<endl;
return;
}
int sizeFileHeader=sizeof(BITMAPFILEHEADER);
int sizeInfoHeader=sizeof(BITMAPINFOHEADER);
WORD fileType;
DWORD fileSize;
DWORD dataOffSet;
BITMAPFILEHEADER* bitmapFileHeader=new BITMAPFILEHEADER[sizeFileHeader+1];
DWORD sizeImage=0;
BITMAPINFOHEADER* bitmapInfoHeader=new BITMAPINFOHEADER[sizeInfoHeader+1];
memset(bitmapFileHeader,0,sizeFileHeader+1);
memset(bitmapInfoHeader,0,sizeInfoHeader+1);
fread(bitmapFileHeader,sizeof(char),sizeFileHeader,stream);
fseek(stream,sizeFileHeader,0);
fread(bitmapInfoHeader,sizeof(char),sizeInfoHeader,stream);
//************位图文件头**********************
fileType=bitmapFileHeader->bfType;
if(fileType!=0x4d42)
{
cout<<"这不是一个bmp文件"<<endl;
return;
}
fileSize=bitmapFileHeader->bfSize;
dataOffSet=bitmapFileHeader->bfOffBits;
cout<<hex<<fileSize<<endl;
cout<<hex<<dataOffSet<<endl;
//************位图信息头**********************
sizeImage=bitmapInfoHeader->biSizeImage;
BYTE* data=new BYTE[sizeImage+1];
memset(data,0,sizeImage+1);
cout<<bitmapInfoHeader->biSize<<endl;
cout<<bitmapInfoHeader->biHeight<<endl;
cout<<bitmapInfoHeader->biWidth<<endl;
cout<<bitmapInfoHeader->biBitCount<<endl;
cout<<sizeImage<<endl;
//***********位图数据***********************
fseek(stream,sizeFileHeader+sizeInfoHeader,0);
fread(data,sizeof(BYTE),sizeImage,stream);
fclose(stream);
for(int i=0;i<221;i++)
{
data[i]=0;
}
//完全自己自定义一个文件,把原来的那个文件的数据复制到我们创建的文件中。
FILE* fileWrite=fopen("D:\\5.bmp","a+");
fwrite(bitmapFileHeader,sizeof(char),sizeFileHeader,fileWrite);
fwrite(bitmapInfoHeader,sizeof(char),sizeInfoHeader,fileWrite);
fwrite(data,sizeof(char),sizeImage,fileWrite);
fclose(fileWrite);
}
你会发现新的文件和原来的文件确实差不多相同,唯一不同的是新图片的左下角会有一条黑色的横线,这是
for(int i=0;i<221;i++)
{
data[i]=0;
}
导致的。。。我们的BMP文件存储顺序是从左到右,从下到上,具体请看上面给的链接。。(大端法和小端法,内存对齐这部分内容多看看)。
碰到了个蛋疼的问题,我是创建一个空的工程,发现用DWORD和WORD的时候给我个提示:未声明的标识符。解决这个问题很简单,只要包含进定义这个数据类型的头文件就可以了嘛。。或者自己在从新定义一下这个数据类型:
typedef unsigned long DWORD;
typedef unsigned short WORD;