📄 bmp.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 + -