⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmp.cpp

📁 VC++图像编程
💻 CPP
字号:
/********************************************************************
	created:	2005/06/21
	created:	21:6:2005   21:55
	filename: 	imagetest\bmp.cpp
	file path:	imagetest
	file base:	bmp
	file ext:	cpp
	author:		Gengxun
	
	purpose:	读写BMP
*********************************************************************/
#include "stdafx.h"
#include "bmp.h"

// 声明串行化过程
IMPLEMENT_SERIAL(CBmp, CObject, 0);

CBmp::CBmp() 
{
	m_pBMIH = NULL;
	m_pBits = NULL;
}

CBmp::~CBmp()
{
	if (m_pBMIH != NULL)
	{
		delete m_pBMIH;
		m_pBMIH = NULL;
	}

	if(m_pBits != NULL)
	{
		m_pBits = NULL;
	}
}
/*************************************************
Function:       Read
Description:    读取BMP图像
Input:          CFile *pFile
Output:         
Return:         BOOL  成功返回TRUE,否则返回FALSE
Others:         读取文件头、信息头、调色板和图像数据 
*************************************************/
BOOL CBmp::Read(CFile *pFile)
{
	// 进行读操作
	try 
	{
		BITMAPFILEHEADER bmfh;
		
		// 步骤1 读取文件头
		int nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
		
		// 判断是否是BMP格式的位图
		if(bmfh.bfType != BMP_HEADER_MARKER) 
		{
			throw new CException;
		}
		
		// 计算信息头加上调色板的大小并分内存
		int nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
		m_pBMIH = (LPBITMAPINFOHEADER) new BYTE[nSize];

		// 步骤2 读取信息头和调色板
		nCount = pFile->Read(m_pBMIH, nSize); 
		
		// 步骤3 读取图象数据
		m_pBits = (LPBYTE) new BYTE[m_pBMIH->biSizeImage];
		nCount = pFile->Read(m_pBits, m_pBMIH->biSizeImage); 
	}

	catch(CException* pe) 
	{
		AfxMessageBox("Read error");
		pe->Delete();
		return FALSE;
	}

	return TRUE;
}

/*************************************************
Function:       Write
Description:    写入BMP图像
Input:          CFile *pFile
Output:         
Return:         BOOL  成功返回TRUE,否则返回FALSE
Others:         BMP格式的图像以“BM”为开始标志
*************************************************/
BOOL CBmp::Write(CFile *pFile)
{
	BITMAPFILEHEADER bmfh;
	
	// 设置文件头中文件类型 0x424D="BM"
	bmfh.bfType = BMP_HEADER_MARKER;  
	
	// 计算信息头和调色板大小
	int nSizeHeader = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetPaletteSize();
	
	// 设置文件头信息
	bmfh.bfSize      = sizeof(BITMAPFILEHEADER) + nSizeHeader + GetImageSize();
	bmfh.bfReserved1 = 0;
	bmfh.bfReserved2 = 0;

	//计算偏移量 文件头大小+信息头大小+调色板大小
	bmfh.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) 
		             + sizeof(RGBQUAD) * GetPaletteSize();	
	
	// 进行写操作
	try 
	{
		pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
		pFile->Write((LPVOID) m_pBMIH,  nSizeHeader);
		pFile->Write((LPVOID) m_pBits, GetImageSize());
	}	

	catch(CException* pe)
	{
		pe->Delete();
		AfxMessageBox("write error");
		return FALSE;
	}
	
	return TRUE;
}


//图像的大小
DWORD CBmp::GetImageSize()
{
	return m_pBMIH->biSizeImage;
}

//计算调色板的大小
int CBmp::GetPaletteSize()
{
	int ret = 0;

	if(m_pBMIH->biClrUsed == 0) 	// 调色板的大小为2的biBitCount次方		
	{
		switch(m_pBMIH->biBitCount)
		{
		case 1:
			ret = 2;
			break;
		case 4:
			ret = 16;
			break;
		case 8:
			ret = 256;
			break;
		case 16:
		case 24:
		case 32:
			ret = 0;
			break;
		default:
			ret = 0;
		}
	}	
	else // 调色板的大小为实际用到的颜色数
	{
		ret = m_pBMIH->biClrUsed;
	}

	return ret;
}

//串行化
void CBmp::Serialize(CArchive &ar)
{

	if(ar.IsStoring()) 
	{
		Write(ar.GetFile());
	}
	else 
	{
		Read(ar.GetFile());
	}
}
BOOL CBmp::MakePalette()
{
	if(GetPaletteSize()==0)
	{
	return FALSE;
	}
	if(m_hPalette!=NULL)
	{
		::DeleteObject(m_hPalette);
	}
	LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char [2*sizeof(WORD)+GetPaletteSize()*sizeof(PALETTEENTRY)];
	pLogPal->palVersion=0x300;
	pLogPal->palNumEntries=GetPaletteSize();
	LPRGBQUAD pDibQuad = (LPRGBQUAD) GetColorTable();
	for(int i=0;i<GetPaletteSize();++i)
	{
		pLogPal->palPalEntry[i].peRed=
	}
	


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -