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

📄 cdib.cpp

📁 虹膜图像预处理
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "math.h"
#include "process.h"

#include "cdib.h"
#include "GlobalApi.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

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


/*************************************************************************
 *
 * \函数名称:
 *   CDib()
 *
 * \输入参数:
 * 无
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   构造函数
 *
 ************************************************************************
 */
CDib::CDib()
{
	m_hFile      = NULL;			//文件句柄
	m_hBitmap    = NULL;			// BITMAP结构指针
	m_hPalette   = NULL;			//调色板指针
	m_nBmihAlloc = m_nImageAlloc = noAlloc;		//内存分配的情况
	Empty();			// 清空DIB,释放已经分配的内存,并且关闭映射文件
}
/*************************************************************************
 *
 * \函数名称:
 *   CDib()
 *
 * \输入参数:
 * CSize	size			- 位图尺寸
 * int		nBitCount		- 象素位数
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   构造函数
 *   根据给定的位图尺寸和象素位数构造CDib对象,并对信息头和调色板分配内存
 *   但并没有给位图数据分配内存
 *
 ************************************************************************
 */
CDib::CDib(CSize size, int nBitCount)
{
	m_hFile      = NULL;
	m_hBitmap    = NULL;
	m_hPalette   = NULL;
	m_nBmihAlloc = m_nImageAlloc = noAlloc;			//表示没有分配
	Empty();

	// 根据象素位数计算调色板尺寸
	ComputePaletteSize(nBitCount);

	// 分配DIB信息头和调色板的内存
	m_lpBMIH = (LPBITMAPINFOHEADER) new 
		char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];

	// 设置信息头内存分配状态
	m_nBmihAlloc = crtAlloc;			//表示分配了DIB信息头和调色板的内存,但是没有像素数据

	// 设置信息头中的信息
	m_lpBMIH->biSize	= sizeof(BITMAPINFOHEADER);
	m_lpBMIH->biWidth	= size.cx;					//文件的宽度
	m_lpBMIH->biHeight	= size.cy;
	m_lpBMIH->biPlanes	= 1;						//平面数
	m_lpBMIH->biBitCount	= nBitCount;
	m_lpBMIH->biCompression = BI_RGB;				//压缩方式为RGB
	m_lpBMIH->biSizeImage	= 0;					//图象数据内存大小		
	m_lpBMIH->biXPelsPerMeter = 0;
	m_lpBMIH->biYPelsPerMeter = 0;
	m_lpBMIH->biClrUsed	= m_nColorTableEntries;		//调色板大小
	m_lpBMIH->biClrImportant= m_nColorTableEntries;		

	// 计算图象数据内存的大小,并设置此DIB的调色板的指针
	ComputeMetrics();

	// 将此DIB的调色板初始化为0
	memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);

	// 暂时不分配图象数据内存
	m_lpImage = NULL; 
}


/*************************************************************************
 *
 * \函数名称:
 *   ~CDib()
 *
 * \输入参数:
 * 无
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   析构函数,并释放所有分配的DIB内存
 *
 ************************************************************************
 */
CDib::~CDib()
{
	Empty();
}


/*************************************************************************
 *
 * \函数名称:
 *   GetDimensions()
 *
 * \输入参数:
 *   无
 *
 * \返回值:
 *   CSize				- DIB的宽度和高度
 *
 * \说明:
 *   返回以象素表示的DIB的宽度和高度
 *
 ************************************************************************
 */
CSize CDib::GetDimensions()
{	
	if(m_lpBMIH == NULL) return CSize(0, 0);
	return CSize((int) m_lpBMIH->biWidth, (int) m_lpBMIH->biHeight);
}

/*************************************************************************
 *
 * \函数名称:
 *   Draw()
 *
 * \输入参数:
 *   CDC*	pDC			- 指向将要接收DIB图象的设备上下文指针
 *   CPoint	origin			- 显示DIB的逻辑坐标
 *   CSize	size			- 显示矩形的宽度和高度
 *
 * \返回值:
 *   BOOL				- 如果成功,则为TRUE,
 *
 * \说明:
 *   通过调用Win32 SDK的StretchDIBits函数将CDib对象输出到显示器(或者打印机)。
 *   为了适合指定的矩形,位图可以进行必要的拉伸
 *
 ************************************************************************
 */
BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)
{
	// 如果信息头为空,表示尚未有数据,返回FALSE
	if(m_lpBMIH == NULL) return FALSE;

	// 如果调色板不为空,则将调色板选入设备上下文
	if(m_hPalette != NULL) {
		::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
	}

	// 设置显示模式
	pDC->SetStretchBltMode(COLORONCOLOR);

	// 在设备的origin位置上画出大小为size的图象
	::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y,size.cx,size.cy,
		0, 0, m_lpBMIH->biWidth, m_lpBMIH->biHeight,
		m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);

	// 返回
	return TRUE;
}

/*************************************************************************
 *
 * \函数名称:
 *   MakePalette()
 *
 * \输入参数:
 *   无
 *
 * \返回值:
 *   BOOL				- 如果成功,则为TRUE
 *
 * \说明:
 *   如果颜色表存在的话,该函数将读取它,并创建一个Windows调色板。
 *   HPALETTE存储在一个数据成员中。
 *
 ************************************************************************
 */
BOOL CDib::MakePalette()
{
	// 如果不存在调色板,则返回FALSE
	if(m_nColorTableEntries == 0) return FALSE;

	if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
	TRACE("CDib::MakePalette -- m_nColorTableEntries = %d\n", m_nColorTableEntries);
	
	// 给逻辑调色板分配内存
	LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
		m_nColorTableEntries * sizeof(PALETTEENTRY)];

	// 设置逻辑调色板的信息
	pLogPal->palVersion = 0x300;
	pLogPal->palNumEntries = m_nColorTableEntries;

	// 拷贝DIB中的颜色表到逻辑调色板
	LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;
	for(int i = 0; i < m_nColorTableEntries; i++) {
		pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
		pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
		pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
		pLogPal->palPalEntry[i].peFlags = 0;
		pDibQuad++;
	}

	// 创建逻辑调色板
	m_hPalette = ::CreatePalette(pLogPal);

	// 删除临时变量并返回TRUE
	delete pLogPal;
	return TRUE;
}	

/*************************************************************************
 *
 * \函数名称:
 *   Read()
 *
 * \输入参数:
 *   CFile*	pFile			- 指向CFile对象的指针
 *
 * \返回值:
 *   BOOL				- 如果成功,则返回TRUE
 *
 * \说明:
 *   该函数DIB从一个文件读入CDib对象。该文件必须成功打开。如果该文件是BMP文件
 *   读取工作从文件头开始。如果该文件是一个文档,读取工作则从当前文件指针处开始 
 *
 ************************************************************************
 */
BOOL CDib::Read(CFile* pFile)
{
	// 释放已经分配的内存
	Empty();

	// 临时存放信息的变量
	int nCount, nSize;
	BITMAPFILEHEADER bmfh;

	// 进行读操作
	try 
	{
		// 读取文件头
		nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
		if(nCount != sizeof(BITMAPFILEHEADER)) {
			throw new CException;
		}

		// 如果文件类型部位"BM",则返回并进行相应错误处理
		if(bmfh.bfType != 0x4d42) {
			throw new CException;							//?
		}

		// 计算信息头加上调色板的大小,并分配相应的内存
		nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
		m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
		m_nBmihAlloc = m_nImageAlloc = crtAlloc;

		// 读取信息头和调色板
		nCount = pFile->Read(m_lpBMIH, nSize); 

		// 计算图象数据大小并设置调色板指针
		ComputeMetrics();

		// 计算调色板的表项数
		ComputePaletteSize(m_lpBMIH->biBitCount);

		// 如果DIB中存在调色板,则创建一个Windows调色板
		MakePalette();

		// 分配图象数据内存,并从文件中读取图象数据
		m_lpImage = (LPBYTE) new char[m_dwSizeImage];
		nCount = pFile->Read(m_lpImage, m_dwSizeImage); 
	}

	// 错误处理
	catch(CException* pe) 
	{
		AfxMessageBox("Read error");
		pe->Delete();
		return FALSE;
	}

	// 返回
	return TRUE;
}

/*************************************************************************
 *
 * \函数名称:
 *   Write()

⌨️ 快捷键说明

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