您的位置:首页 > 编程语言 > C语言/C++

C++ bmp文件读写操作

2013-11-25 22:25 323 查看
bmp文件,总的说来,可以分为以下4个部分

1. 文件头-----FILE_HEADER (总共14个字节)

2. 信息头-----INFO_HEADER  (总共40个字节)

3. 调色板----PALLET (单通道灰度图像才有,真彩色3通道图像没有)

4. 图像数据---IMAGE_DATA (实际图象像素数据)

bmp位图文件读写和显示到指定控件api简单封装,下面给出了封装源码的链接地址,欢迎大家一起交流,共同进步。

下载链接:http://download.csdn.net/detail/cimage/6610213

分别基本结构定义如下:

1. 文件头

struct tagBmpFileHeader //文件头
{
unsigned short bfType;		//标识该文件为bmp文件,判断文件是否为bmp文件,即用该值与"0x4d42"比较是否相等即可,0x4d42 = 19778
unsigned long  bfSize;		//文件大小
unsigned short bfReserved1;	//预保留位
unsigned short bfReserved2;	//预保留位
unsigned long  bfOffBits;	//图像数据区的起始位置
}BmpFileHeader;//14字节
2. 信息头

struct tagBmpInfoHeader //信息头
{
unsigned long  biSize;	//图像数据大小
long     biWidth;	//宽度
long     biHeight;	//高度
unsigned short biPlanes;//为1
unsigned short biBitCount; //像素位数,8-灰度图;24-真彩色
unsigned longbiCompression;//压缩方式
unsigned longbiSizeImage;  //图像区数据大小
long     biXPelsPerMeter;  //水平分辨率,像素每米
long     biYPelsPerMeter;
unsigned long biClrUsed;   //位图实际用到的颜色数
unsigned short biClrImportant;//位图显示过程,重要的颜色数;0--所有都重要
}BmpInfoHeader;//40字节
3. 调色板

struct tagRGBPallete //调色板
{
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char alpha; //预保留位
}RGBPallete;


4. 定义一个图像结构

typedef struct tagVImage
{
int width;
int height;
int channels;
unsigned char* data;
}VImage;

5. bmp图像读取

VImage* LoadBMP(const char* filename)
{
VImage* tempImage = (VImage*)malloc(sizeof(VImage));

ULONGLONG position = 0;//文件中内容地址

int szBmpFileHeader = 0, szBmpInfoHeader = 0, szRGBPallete = 0, szTemp = 0;

int width = 0, height = 0, nChannels = 0, widthStep = 0, index = 0;

unsigned char* dataBuff = NULL;

CFile bmpFile;

if (!bmpFile.Open(filename, CFile::modeRead | CFile::shareDenyWrite))
return NULL;

szBmpFileHeader = sizeof(BmpFileHeader);
szBmpInfoHeader = sizeof(BmpInfoHeader);
szRGBPallete    = sizeof(RGBPallete);

BmpFileHeader* pFileHeader = (BmpFileHeader*)malloc(szBmpFileHeader);

szTemp = bmpFile.Read(pFileHeader, szBmpFileHeader); //文件头读取完毕

position = bmpFile.Seek(szBmpFileHeader, CFile::begin); //跳转到文件头后地址处

if (szTemp != szBmpFileHeader)
return NULL;

if (pFileHeader->bfType != 0x4d42)// 0x4d42 = 19778
return NULL;

BmpInfoHeader* pInfoHeader = (BmpInfoHeader*) malloc(szBmpInfoHeader);

bmpFile.Read(pInfoHeader, szBmpInfoHeader); //信息头读取完毕

position = bmpFile.Seek(szBmpInfoHeader + position, CFile::begin);//跳转到信息头后

width = pInfoHeader->biWidth;
height = pInfoHeader->biHeight;

width = ((width + 3) >> 2) << 2;

if (8 == pInfoHeader->biBitCount)//灰度图
{
RGBPallete* pRGBPallete = (RGBPallete*) malloc(256 * szRGBPallete);

bmpFile.Read(pRGBPallete, 256 * szRGBPallete);//灰度图,读取调色板完毕

position = bmpFile.Seek(256 * szRGBPallete + position, CFile::begin);

nChannels = 1;
widthStep = width;

tempImage->width = width;
tempImage->height = height;
tempImage->channels = nChannels;

tempImage->data = (unsigned char*) malloc(width * height);

dataBuff = (unsigned char*) malloc(width * height);
memset(dataBuff, 0, width * height);

//bmpFile.Read(tempImage->data, width * height);//图像实际数据读取完毕
bmpFile.Read(dataBuff, width * height);//图像实际数据读取完毕

for (index = 0; index < height; index++)//bmp数据分布格式
{
memcpy(tempImage->data + index * width, dataBuff + (height - 1 - index) * width, width);
}

free(pFileHeader);
free(pInfoHeader);
free(pRGBPallete);
free(dataBuff);

pFileHeader = NULL;
pInfoHeader = NULL;
pRGBPallete = NULL;
dataBuff = NULL;

bmpFile.Close();//关闭文件

return tempImage;
}
else if (24 == pInfoHeader->biBitCount) // 真彩色
{
nChannels = 3;
widthStep = width * 3;

tempImage->width = width;
tempImage->height = height;
tempImage->channels = nChannels;

tempImage->data = (unsigned char*) malloc(widthStep * height);
dataBuff = (unsigned char*) malloc(widthStep * height);

//bmpFile.Read(tempImage->data, widthStep * height);
bmpFile.Read(dataBuff, widthStep * height);

for (index = 0; index < height; index++)//bmp数据分布格式为左下角到右上角,因此转换一下。
{
memcpy(tempImage->data + index * widthStep, dataBuff + (height - 1 - index) * widthStep, widthStep);
}

free(pFileHeader);
free(pInfoHeader);
free(dataBuff);

dataBuff = NULL;
pFileHeader = NULL;
pInfoHeader = NULL;

bmpFile.Close();

return tempImage;
}
return NULL;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: