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

📄 dib.cpp

📁 单文档中打开图片
💻 CPP
字号:
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Dib.h"

#include <math.h>

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDib::CDib()
{
	InitMembers();
}

CDib::~CDib()
{
	ClearMemory();
}

/*************************************************************************
 * 函数名称:ConstructPalette(HGLOBAL hDIB, CPalette* pPal)
 * 函数参数:
 *   HGLOBAL hDIB,DIB对象的句柄
 *   CPalette* pPal,调色板的指针
 * 函数类型:BOOL
 * 函数说明:该函数按照DIB创建一个逻辑调色板  
 ************************************************************************/

BOOL CDib::ConstructPalette(HGLOBAL hDIB, CPalette* pPal)
{	
	
	HANDLE hLogPal;// 逻辑调色板的句柄	
	int iLoop;// 循环变量	
	BOOL bSuccess = FALSE;// 创建结果	
	if (hDIB == NULL)//判断是否是有效的DIB对象
	{		
		return FALSE;// 返回FALSE
	}	
	lpdib = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);// 锁定DIB
	lpbminfo= (LPBITMAPINFO)lpdib;			
	long wNumColors =GetColorNum(lpdib);// 获取DIB中颜色表中的颜色数目	
	if (wNumColors != 0)
	{		
		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)// 分配为逻辑调色板内存
									+ sizeof(PALETTEENTRY)
									* wNumColors);	
		if (hLogPal == 0)// 如果失败则退出
		{			
			::GlobalUnlock((HGLOBAL) hDIB);// 解除锁定			
			return FALSE;
		}		
		LPLOGPALETTE lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);		
		
		lpPal->palVersion = 0x300;// 设置调色板版本号				
		lpPal->palNumEntries = (WORD)wNumColors;// 设置颜色数目		
		for (iLoop=0; iLoop<(int)wNumColors;iLoop++)// 读取调色板
		{			
			lpPal->palPalEntry[iLoop].peRed =lpbminfo->bmiColors[iLoop].rgbRed;// 读取三原色分量						
			lpPal->palPalEntry[iLoop].peGreen =lpbminfo->bmiColors[iLoop].rgbGreen;							
			lpPal->palPalEntry[iLoop].peBlue =lpbminfo->bmiColors[iLoop].rgbBlue;								
			lpPal->palPalEntry[iLoop].peFlags =0;// 保留位			
		}		
		bSuccess=pPal->CreatePalette(lpPal);// 按照逻辑调色板创建调色板,并返回指针			
		::GlobalUnlock((HGLOBAL) hLogPal);// 解除锁定				
		::GlobalFree((HGLOBAL) hLogPal);// 释放逻辑调色板
	}		
	::GlobalUnlock((HGLOBAL) hDIB);// 解除锁定		
	return bSuccess;// 返回结果
}

/*************************************************************************
 * 函数名称:GetBits(LPSTR lpdib)
 * 函数参数:
 *   LPSTR lpdib,指向DIB对象的指针
 * 函数类型:LPSTR 
 * 函数功能:计算DIB像素的起始位置,并返回指向它的指针
 ************************************************************************/

LPSTR CDib::GetBits(LPSTR lpdib)
{
	return (lpdib + ((LPBITMAPINFOHEADER)lpdib)->biSize+GetPalSize(lpdib));
//	return (lpdib + *(LPDWORD)lpdib+GetPalSize(lpdib));
}

/*************************************************************************
 * 函数名称:GetWidth(LPSTR lpdib)
 * 函数参数:
 *   LPSTR lpdib,指向DIB对象的指针
 * 函数类型:DWORD
 * 函数功能:该函数返回DIB中图象的宽度
 ************************************************************************/

DWORD CDib::GetWidth(LPSTR lpdib)
{
	return ((LPBITMAPINFOHEADER)lpdib)->biWidth;//返回DIB宽度
}


/*************************************************************************
 * 函数名称:GetHeight(LPSTR lpdib)
 * 函数参数:
 *   LPSTR lpdib ,指向DIB对象的指针
 * 函数类型:DWORD
 * 函数功能:该函数返回DIB中图象的高度
 ************************************************************************/


DWORD CDib::GetHeight(LPSTR lpdib)
{
	return ((LPBITMAPINFOHEADER)lpdib)->biHeight;//返回DIB高度

}
/*************************************************************************
 * 函数名称:GetPalSize(LPSTR lpdib)
 * 函数参数:
 *   LPSTR lpdib,指向DIB对象的指针
 * 函数类型:WORD
 * 函数功能:该函数返回DIB中调色板的大小
 ************************************************************************/

WORD CDib::GetPalSize(LPSTR lpdib)
{	
	return (WORD)(GetColorNum(lpdib) * sizeof(RGBQUAD));// 计算DIB中调色板的大小
}

/*************************************************************************
 * 函数名称:GetColorNum(LPSTR lpdib)
 * 函数参数:
 *   LPSTR lpdib,指向DIB对象的指针
 * 函数类型:WORD
 * 函数功能:该函数返回DIB中调色板的颜色的种数
 ************************************************************************/
WORD CDib::GetColorNum(LPSTR lpdib)
{	
	long dwClrUsed = ((LPBITMAPINFOHEADER)lpdib)->biClrUsed;	// 读取dwClrUsed值	
	
	if (dwClrUsed != 0)
	{			
		return (WORD)dwClrUsed;// 如果dwClrUsed不为0,直接返回该值
	}
	else
	{
		dwClrUsed=(long)pow(2,24);
		return (WORD)dwClrUsed;
	}
}

/*************************************************************************
 * 函数名称:GetBitCount(LPSTR lpdib)
 * 函数参数:
 *   LPSTR lpdib,指向DIB对象的指针
 * 函数类型:WORD 
 * 函数功能:该函数返回DIBBitCount
 ************************************************************************/
WORD CDib::GetBitCount(LPSTR lpdib)
{
	return ((LPBITMAPINFOHEADER)lpdib)->biBitCount;// 返回位宽
}


/*************************************************************************
 * 函数名称:LoadFile(CFile& file)
 * 函数参数:
 *   CFile& file,要读取得文件文件CFile
 * 函数类型:HGLOBAL
 * 函数功能:将指定的文件中的DIB对象读到指定的内存区域中
 *************************************************************************/

HGLOBAL CDib::LoadFile(CFile& file)
{

	DWORD dwFileSize;
	
	dwFileSize= file.GetLength();//获取文件大小	
	if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))// 读取DIB文件头
	{		
		return NULL;// 大小不一致,返回NULL
	}
	// 如果文件类型不是"BM",其16进制值为0x4d42,则返回并进行相应错误处理
	if (bmfHeader.bfType !=0x4d42)
	{		
		return NULL;// 如果不是则返回NULL
	}	
	m_hDib= (HGLOBAL) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwFileSize-sizeof(BITMAPFILEHEADER));// 分配DIB内存
	if (m_hDib==NULL)
	{		
		return NULL;// 分配失败,返回NULL
	}
	/////////////////////////////////////////////////////////////////////////
	//给CDib类的成员变量赋值	
	lpdib = (LPSTR) ::GlobalLock((HGLOBAL) m_hDib);// 锁定	
	if (file.ReadHuge(lpdib, dwFileSize - sizeof(BITMAPFILEHEADER)) !=// 读像素
		dwFileSize - sizeof(BITMAPFILEHEADER) )//大小不一致
	{					
		::GlobalUnlock((HGLOBAL) m_hDib);	// 解除锁定			
		::GlobalFree((HGLOBAL) m_hDib);	// 释放内存
		return NULL;
	}		
	::GlobalUnlock((HGLOBAL) m_hDib);// 解除锁定		
	return m_hDib;// 返回DIB句柄
}

/*************************************************************************
 * 函数名称:GetReqByteWidth(int bits)
 * 函数参数:
 *   int bits,位数
 * 函数类型:int
 * 函数功能:获取需要的行字节数,应为4的倍数
 *************************************************************************/
int  CDib::GetReqByteWidth(int bits)
{
	int getBytes=(bits + 31) / 32 * 4;
	return  getBytes;
}

/*************************************************************************
 * 函数名称:GetRectWidth(LPCRECT lpRect)
 * 函数参数:
 *   LPCRECT lpRect,指向矩形区域的指针
 * 函数类型:long
 * 函数功能:获取矩形区域的宽度
 *************************************************************************/

long  CDib::GetRectWidth(LPCRECT lpRect)
{
	long nWidth=lpRect->right - lpRect->left;
	return nWidth;
}
/*************************************************************************
 * 函数名称:GetRectHeight(LPCRECT lpRect)
 * 函数参数:
 *   LPCRECT lpRect,指向矩形区域的指针
 * 函数类型:long
 * 函数功能:获取矩形区域的高度
 *************************************************************************/
long  CDib::GetRectHeight(LPCRECT lpRect)
{
	long nHeight=lpRect->bottom - lpRect->top;
	return nHeight;
}

/*************************************************************************
 * 函数名称:InitMembers() 
 * 函数类型: void
 * 函数功能:初始化类的成员变量
 *************************************************************************/
void CDib::InitMembers()
{
	m_hDib=NULL;
	lpdib=NULL;
	lpDIBBits=NULL;
}

/*************************************************************************
 * 函数名称:ClearMemory() 
 * 函数类型: void
 * 函数功能:复位类的成员变量
 *************************************************************************/
void CDib::ClearMemory()
{
	if(m_hDib!=NULL)
		::GlobalFree(m_hDib);
	lpdib=NULL;
}

/*************************************************************************
 * 函数名称:SaveFile(HGLOBAL hDib, CFile& file)
 * 函数参数:
 *   HGLOBAL hDib,要保存的DIB
 *   CFile& file,保存文件CFile
 * 函数类型:BOOL
 * 函数功能:将指定的DIB对象保存到指定的CFile中
 *************************************************************************/

BOOL CDib::SaveFile(HGLOBAL hDib, CFile& file)
{
	if (hDib == NULL)
	{		
		return FALSE;// 如果DIB为空,返回FALSE
	}	
	lpbmihrd = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);// 读取BITMAPINFO结构,并锁定	
	if (lpbmihrd == NULL)
	{		
		return FALSE;// 为空,返回FALSE
	}		
	bmfHeader.bfType ='BM';	// 填充文件头	
	dwDIBSize = *(LPDWORD)lpbmihrd + GetPalSize((LPSTR)lpbmihrd);// 文件头大小+颜色表大小			
	DWORD dwBmBitsSize;// 像素的大小		
	dwBmBitsSize =GetReqByteWidth((lpbmihrd->biWidth)*((DWORD)lpbmihrd->biBitCount)) * lpbmihrd->biHeight;// 大小为Width * Height		
	dwDIBSize += dwBmBitsSize;// 计算后DIB每行字节数为4的倍数时的大小
	lpbmihrd->biSizeImage = dwBmBitsSize;// 更新biSizeImage	
	bmfHeader.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);// 文件大小		
	bmfHeader.bfReserved1 = 0;// 两个保留字
	bmfHeader.bfReserved2 = 0;
	bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpbmihrd->biSize// 计算偏移量bfOffBits
							+ GetPalSize((LPSTR)lpbmihrd);
	file.Write(&bmfHeader, sizeof(BITMAPFILEHEADER));// 写文件头				
	file.WriteHuge(lpbmihrd, dwDIBSize);// 写DIB头和像素
	
	::GlobalUnlock((HGLOBAL) hDib);// 解除锁定	
	return TRUE;// 返回TRUE
}

⌨️ 快捷键说明

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