BMP文件结构读写操作(图文) c实现

BMP文件结构

BMP文件结构及其存取

BMP文件结构

 

BMP图像文件的读写

BMP文件的读入

readBmp()函数实现了BMP文件的读取操作,下面的代码是对readBmp()函数的说明和实现。

/*
*函数名称:
*	readBmp()
*
*函数参数:
*	char *bmpName-文件名字及路径
*
*返回值:
*	0为失败,1为成功
*
*说明:给定一个图像文件名及其路径,读图像
*的位图数据、宽、高、颜色表及每像素位数等
*数据进内存,存放在相应的全局变量中。
*
*/
bool readBmp(char *bmpName)
{
	//二进制读方式打开指定的图像文件
	FILE *fp = fopen(bmpName, "rb");
	if (fp == 0)
	{
		return 0;
	}
	//跳过位图文件头结构BITMAPFILEHEADER
	fseek(fp, sizeof(BITMAPFILEHEADER), 0);

	//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
	BITMAPINFOHEADER head;
	fread(&head, sizeof(BITMAPINFOHEADER), 1, fp);
	//获取图像宽、高、每像素所占位数等信息
	bmpWidth = head.biWidth;
	bmpHeight = head.biHeight;
	biBitCount = head.biBitCount;
	//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
	int lineByte = (bmpWidth*biBitCount / 8 + 3) / 4 * 4;
	//灰度图像有颜色表,且颜色表表项为256
	if (biBitCount == 8)
	{
		//申请颜色表所需要的空间,读颜色表进内存
		pColorTable = new RGBQUAD[256];
		fread(pColorTable, sizeof(RGBQUAD), 256, fp);
	}
	//申请位图数据所需要的空间,读位图数据进内存
	pBmpBuf = new unsigned char[lineByte*bmpHeight];
	fread(pBmpBuf, 1, lineByte*bmpHeight, fp);
	//关闭文件
	fclose(fp);
	return 1;
}

BMP文件的存盘

saveBmp()函数实现了BMP文件的读写操作,该函数的说明及代码实现如下。


/*
*函数名称:
*	saveBmp()
*
*函数参数:
*	char *bmpName-文件名字及路径
*	unsigned char *imgBuf-待存盘的位图数据
*	int width-以像素为单位待存盘位图宽
*	int height-以像素为单位待存盘位图高
*	int biBitCount-每像素所占位数
*	RGBQUAD *pColorTable-颜色表指针
*
*返回值:
*	0为失败,1为成功
*
*说明:给定一个图像的图像的位图数据、宽、
*高、颜色表及每像素所占的位数等信息,
*将其写到指定文件中。
*
*/
bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,int biBitCount, RGBQUAD *pColorTable)
{
	//如果位图数据指针为0,则没有数据传入,函数返回
	if (!imgBuf) return 0;
	//颜色表大小,以字节为单位,灰度图像颜色表为1024
	//字节,彩色图像颜色表大小为0
	int colorTablesize = 0;
	if (biBitCount == 8)
	{
		colorTablesize = 1024;
	}
	//待存储图像数据每行字节数为4的倍数
	int lineByte = (width*biBitCount / 8 + 3) / 4 * 4;
	//以二进制写的方式打开文件
	FILE *fp = fopen(bmpName, "wb");
	if (fp == 0) return 0;
	//申请位图文件头结构变量,填写文件头信息
	BITMAPFILEHEADER fileHead;
	fileHead.bfType = 0x4D42;
	//bfSize是图像文件4个组成部分之和
	fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte * height;
	fileHead.bfReserved1 = 0;
	fileHead.bfReserved2 = 0;
	//bfOffBits是图像文件前3个部分所需空间之和
	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);
	//如果灰度图像,有颜色表,写入文件
	if (biBitCount == 8)
	{
		fwrite(pColorTable, sizeof(RGBQUAD), 256, fp);
	}
	//写位图数据进文件
	fwrite(imgBuf, height*lineByte, 1, fp);
	//关闭文件
	fclose(fp);
	return 1;
}

对于readBmp()和saveBmp()函数的简单调用如下:

void main()
{
	//读入指定BMP文件进内存
	char readPath[] = "dog.BMP";
	readBmp(readPath);
	//输出图像的信息
	printf("width=%d,height=%d,biBitCount=%d\n", bmpWidth, bmpHeight, biBitCount);
	//将图像数据存盘
	char writePath[] = "dogcpy.BMP";
	saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);
	//清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
	delete[]pBmpBuf;
	if (biBitCount == 8)
		delete[]pColorTable;
}

结果如图:

BMP图像位图数据的访问

void main()
{
	//读入指定BMP文件进内存
	char readPath[] = "dog.BMP";
	readBmp(readPath);
	//输出图像的信息
	printf("width=%d,height=%d,biBitCount=%d\n", bmpWidth, bmpHeight, biBitCount);
	
	//循环变量,图像的坐标
	int i, j;
	//每行字节数
	int lineByte = (bmpWidth*biBitCount / 8 + 3) / 4 * 4;
	//循环变量,针对彩色图像,遍历每像素的三个分量
	int k;
	//将图像左下角1/4部分置成黑色
	if (biBitCount == 8)
	{
		for (i = 0; i < bmpHeight / 2; i++)
		{
			for (j = 0; j < bmpWidth / 2; j++)
			{
				*(pBmpBuf + i * lineByte + j) = 0;
			}
		}
	}
	else if (biBitCount == 24)//彩色图像
	{
		for (i = 0; i < bmpHeight / 2; i++)
		{
			for (j = 0; j < bmpWidth / 2; j++)
			{
				for (k = 0; k < 3; k++)
				{
					*(pBmpBuf + i * lineByte + j*3+k) = 0;
				}
			}
		}
	}
	//将图像数据存盘
	char writePath[] = "dogcpy.BMP";
	saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);
	//清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
	delete[]pBmpBuf;
	if (biBitCount == 8)
		delete[]pColorTable;
}

结果如图:

参考链接:https://wenku.baidu.com/view/901572d5360cba1aa811da61.html

发布了109 篇原创文章 · 获赞 179 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_44350205/article/details/105612261