ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-06-17 14:05:45  阅读:193  来源: 互联网

标签:fp 文件 head biBitCount int 读写操作 BMP 图文


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

 

 

 

标签:fp,文件,head,biBitCount,int,读写操作,BMP,图文
来源: https://blog.51cto.com/u_15273495/2915297

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有