[C/C++]读写BMP文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24380063/article/details/70231285

BMP格式详细资料请参考:[Baidu]链接 [Wiki]链接 [博客]链接

需要包含的头文件

#include <Windows.h>
#include <stdio.h>

1. 读8位BMP(灰度图).

BYTE* Read8BMP( int &nWidth,
				int &nHeight,
				const char *strFileName)
{
	if (!strFileName)	return NULL;

	BITMAPFILEHEADER	FileHeader;
	BITMAPINFOHEADER	InfoHeader;
	FILE				*fp;
	BYTE				*pImg, *pCur;
	BYTE				tmp;
	int 				ImgSize, Extend, i;

	if ((fp=fopen(strFileName, "rb")) == NULL) return NULL;
	if (fread((void *)&FileHeader, 1, 14, fp) != 14){ fclose(fp); return NULL; }
	if (fread((void *)&InfoHeader, 1, 40, fp) != 40){ fclose(fp); return NULL; }
	if (FileHeader.bfOffBits < 54){ fclose(fp); return NULL; }
	if (InfoHeader.biBitCount != 8){ fclose(fp); return NULL; }

	nWidth = (int)InfoHeader.biWidth;
	nHeight = (int)InfoHeader.biHeight;
	ImgSize = nWidth*nHeight;
	fseek(fp, FileHeader.bfOffBits, SEEK_SET);
	if ((pImg=new BYTE[ImgSize]) == NULL){ fclose(fp); return NULL; }

	Extend = (nWidth + 3)/4*4 - nWidth;
	for (pCur = pImg + ImgSize-nWidth;
		 pCur>= pImg;
		 pCur-= nWidth)
	{
		if (fread((void *)pCur, 1, nWidth, fp) != UINT(nWidth))
			{ delete[]pImg; fclose(fp); return NULL; }
		for (i = 0; i < Extend; i++)
			if(fread(&tmp, 1, 1, fp) != 1)
				{ delete[]pImg; fclose(fp); return NULL; }
	}
	fclose(fp);
	return pImg;
}

2. 写8位BMP(灰度图).

bool Write8BMP( BYTE *pImg,
				INT nWidth,
				INT nHeight,
				const char *strFileName)
{
	if (!strFileName)	return false;
	if (!pImg)			return false;

	BITMAPFILEHEADER	FileHeader;
	BITMAPINFOHEADER	InfoHeader;
	FILE				*fp;
	BYTE				*pCur;
	int					ImgSize, ImgW, Extend, i;
	RGBQUAD				rgbQuad[256];
	

	ImgW = (nWidth+3)/4*4;
	ImgSize = ImgW*nHeight;

	if ((fp = fopen(strFileName, "wb+")) == NULL) return false;
	FileHeader.bfType = ((WORD)('M' << 8) | 'B');
	FileHeader.bfOffBits = 1078; // sizeof(FileHeader)+sizeof(InfoHeader)+ sizeof(rgbQuad[256])
	FileHeader.bfSize = FileHeader.bfOffBits + ImgSize;
	FileHeader.bfReserved1 = 0;
	FileHeader.bfReserved2 = 0;
	
	InfoHeader.biSize = 40;
	InfoHeader.biWidth = nWidth;
	InfoHeader.biHeight = nHeight;
	InfoHeader.biPlanes = 1;
	InfoHeader.biBitCount = 8;
	InfoHeader.biCompression = 0;
	InfoHeader.biSizeImage = ImgSize;
	InfoHeader.biXPelsPerMeter = 0;
	InfoHeader.biYPelsPerMeter = 0;
	InfoHeader.biClrUsed = 0;
	InfoHeader.biClrImportant = 0;
	for (i = 0; i < 256; i++)
	{
		rgbQuad[i].rgbRed = rgbQuad[i].rgbGreen = rgbQuad[i].rgbBlue = BYTE(i);
		rgbQuad[i].rgbReserved = 0;
	}

	if (fwrite((void *)&FileHeader, 1, 14, fp) != 14)
		{ fclose(fp); remove(strFileName); return false; }
	if (fwrite((void *)&InfoHeader, 1, 40, fp) != 40)
		{ fclose(fp); remove(strFileName); return false; }
	if (fwrite((void *)rgbQuad, 1, 1024, fp) != 1024)
		{ fclose(fp); remove(strFileName); return false; }

	Extend = ImgW-nWidth;
	for (pCur = pImg + (nHeight - 1)*nWidth;
		 pCur>= pImg;
		 pCur-= nWidth)
	{
		if (fwrite((void *)pCur, 1, nWidth, fp) != UINT(nWidth))
			{ fclose(fp); remove(strFileName); return false; }

		for (i = 0; i < Extend; i++)
			if (fwrite((void *)(pCur+nWidth-1), 1, 1, fp) != 1)
				{ fclose(fp); remove(strFileName); return false; }
		
	}
	fclose(fp);
	return true;
}

3. 读24位BMP(真彩图).

BYTE* Read24BMP(INT &nWidth,
				INT &nHeight,
				const char *strFileName)
{
	if (!strFileName)	return NULL;

	BITMAPFILEHEADER	FileHeader;
	BITMAPINFOHEADER	InfoHeader;
	FILE*				fp;
	BYTE				*pImg, *pCur;
	BYTE				tmp;
	int					ImgSize, Patch, Extend, i;

	if ((fp = fopen(strFileName, "rb")) == NULL) return NULL;
	if (fread((void *)&FileHeader, 1, 14, fp) != 14){ fclose(fp); return NULL; }
	if (fread((void *)&InfoHeader, 1, 40, fp) != 40){ fclose(fp); return NULL; }
	if (FileHeader.bfOffBits < 54){ fclose(fp); return NULL; }
	if (InfoHeader.biBitCount != 24){ fclose(fp); return NULL; }

	nWidth = (int)InfoHeader.biWidth;
	nHeight = (int)InfoHeader.biHeight;
	Patch = 3*nWidth;
	ImgSize = Patch*nHeight;
	fseek(fp, FileHeader.bfOffBits, SEEK_SET);

	if ((pImg=new BYTE[ImgSize]) == NULL){ fclose(fp); return NULL; }

	Extend = (nWidth*3+3)/4*4 - nWidth*3;
	for (pCur = pImg + ImgSize-Patch;
		 pCur>= pImg;
		 pCur-= Patch)
	{
		if (fread((void *)pCur, 1, Patch, fp) != UINT(Patch))
			{ delete[]pImg; fclose(fp); return NULL;}
		for (i = 0; i < Extend; i++)
			if (fread(&tmp, 1, 1, fp) != 1)
				{ delete[]pImg; fclose(fp); return NULL; }
	}
	fclose(fp);
	return pImg;
}

4. 写24位BMP(真彩图).

bool Write24BMP(BYTE *pImg,
				INT nWidth,
				INT nHeight,
				const char *strFileName)
{
	if (!strFileName)	return false;
	if (!pImg)			return false;

	BITMAPFILEHEADER	FileHeader;
	BITMAPINFOHEADER	InfoHeader;
	FILE				*fp;
	BYTE				*pCur;
	int					ImgSize, Patch, Extend, i;
	
	Patch = nWidth*3;
	ImgSize = (nWidth+3)/4*4 * nHeight;

	if ((fp = fopen(strFileName, "wb+")) == NULL) return false;
	FileHeader.bfType = ((WORD)('M' << 8) | 'B');
	FileHeader.bfOffBits = 54; // sizeof(FileHeader)+sizeof(InfoHeader)
	FileHeader.bfSize = FileHeader.bfOffBits + ImgSize;
	FileHeader.bfReserved1 = 0;
	FileHeader.bfReserved2 = 0;
	
	InfoHeader.biSize = 40;
	InfoHeader.biWidth = nWidth;
	InfoHeader.biHeight = nHeight;
	InfoHeader.biPlanes = 1;
	InfoHeader.biBitCount = 24;
	InfoHeader.biCompression = 0;
	InfoHeader.biSizeImage = ImgSize;
	InfoHeader.biXPelsPerMeter = 0;
	InfoHeader.biYPelsPerMeter = 0;
	InfoHeader.biClrUsed = 0;
	InfoHeader.biClrImportant = 0;

	if (fwrite((void *)&FileHeader, 1, 14, fp) != 14)
		{ fclose(fp); remove(strFileName); return false; }
	if (fwrite((void *)&InfoHeader, 1, 40, fp) != 40)
		{ fclose(fp); remove(strFileName); return false; }

	Extend = (nWidth*3+3)/4*4 - nWidth*3;
	for (pCur = pImg + (nHeight - 1)*Patch;
		 pCur>= pImg;
		 pCur-= Patch)
	{
		if (fwrite((void *)pCur, 1, Patch, fp) != UINT(Patch))
			{ fclose(fp); remove(strFileName); return false; }

		for (i = 0; i < Extend; i++)
			if (fwrite((void *)(pCur + Patch-3), 1, 1, fp) != 1)
				{ fclose(fp); remove(strFileName); return false; }
		
	}
	fclose(fp);
	return true;
}


猜你喜欢

转载自blog.csdn.net/qq_24380063/article/details/70231285