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

📄 cdib.cpp

📁 可用的基于小波的spiht算法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
*/
BOOL CDib::SetSystemPalette(CDC* pDC)
{
	//如果DIB不具备调色板,则需要利用系统的调色板
	if(m_nColorTableEntries != 0) return FALSE;

	//为设备上下文创建中间调色板,并将其与CPalette对象连接
	m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());

	//返回
	return TRUE;
}

/***********************************************************
* \函数名称:
*         UsePalette()
* \输入参数:
*         CDC* pDC            -要实现调色板的设备上下文指针
*         BOOL bBackground    -标记为FALSE(默认值),并且应用程序正在前台运行
*                             -则Windows将把该调色板作为前台调色板来实现。
*      						  -标记为TRUE,则Windows将把该调色板作为后台调色板来实现
* \返回值:
*         UINT                -如果成功,则返回映射到系统调色板的逻辑调色板的表项数
*                             -否则返回GDI_ERROR
* \说明:
*       该函数将CDib对象的逻辑调色板选入设备上下文,然后实现该调色板
*       Draw成员函数在绘制DIB之前调用UsePalette
************************************************************
*/
UINT CDib::UsePalette(CDC* pDC,BOOL bBackground/* = FALSE*/)
{
	//判断是否存在调色板
	if(m_hPalette == NULL) return 0;

	//得到设备上下文句柄
	HDC hdc = pDC->GetSafeHdc();

	//选择调色板到设备上下文
	::SelectPalette(hdc,m_hPalette,bBackground);

	//实现该调色板
	return ::RealizePalette(hdc);
}

/***********************************************************
* \函数名称:
*         CopyPalette()
* \输入参数:
*         HPALETTE hPalSrc    -需要拷贝的源调色板句柄
* \返回值:
*         HPALETTE            -如果成功,则返回拷贝的调色板句柄
* \说明:
*       该函数将创建一个新的调色板,并从指定的调色板拷贝调色板内容
************************************************************
*/
HPALETTE CDib::CopyPalette(HPALETTE hPalSrc)
{
	//调色板指针,临时变量
	PLOGPALETTE plogPal;

	//声明一个调色板句柄和一个临时句柄
	HPALETTE hPalette;
	HANDLE hTemp;

	//调色板表项数
	int iNumEntries = 0;

	//获取调色板中的表项数
	iNumEntries = GetPaletteEntries(hPalSrc,0,iNumEntries,NULL);
	if(iNumEntries == 0)
		return (HPALETTE)NULL;

	//分配调色板内存,得到句柄
	hTemp = GlobalAlloc(GHND,sizeof(DWORD) + sizeof(PALETTEENTRY) * iNumEntries);
	if(!hTemp)
		return (HPALETTE)NULL;

	//得到调色板的指针
	plogPal = (PLOGPALETTE)GlobalLock(hTemp);
	if(!plogPal)
		return (HPALETTE)NULL;

	//设置调色板的信息
	plogPal->palVersion = 0x300;
	plogPal->palNumEntries = (WORD)iNumEntries;

	//获取逻辑调色板中指定范围的调色板表项
	GetPaletteEntries(hPalSrc,0,iNumEntries,plogPal->palPalEntry);

	//创建一个Windows调色板
	hPalette = CreatePalette(plogPal);

	//释放已分配的内存
	GlobalUnlock(hTemp);
	GlobalFree(hTemp);

	//返回调色板句柄
	return hPalette;
}

/***********************************************************
* \函数名称:
*         GetSystemPalette()
* \输入参数:
*         无
* \返回值:
*         HPALETTE            -系统调色板句柄
* \说明:
*       该函数获得当前正使用的系统调色板的句柄
************************************************************
*/
HPALETTE CDib::GetSystemPalette()
{
	//设备上下文
	HDC hDC;

	//声明调色板句柄、指针等临时变量
	static HPALETTE hPal = NULL;
	HANDLE hLogPal;
	LPLOGPALETTE lpLogPal;

	//当前系统调色板的颜色数
	int nColors;

	//获得当前系统设备上下文
	hDC = GetDC(NULL);
	if(!hDC)
		return NULL;

	//获得当前系统调色板的颜色数目
	nColors = (1<<(GetDeviceCaps(hDC,BITSPIXEL) * GetDeviceCaps(hDC,PLANES)));

	//给调色板分配内存
	hLogPal = GlobalAlloc(GHND,sizeof(LOGPALETTE) + nColors * sizeof(PALETTEENTRY));
	if(!hLogPal)
		return NULL;

	//得到调色板内存指针
	lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal);

	//设置调色板信息
	lpLogPal->palVersion = 0x300;
	lpLogPal->palNumEntries = nColors;

	//将系统的调色板拷贝到当前的逻辑调色板中
	GetSystemPaletteEntries(hDC,0,nColors,
		(LPPALETTEENTRY)(lpLogPal->palPalEntry));

	//创建Windows调色板
	hPal = CreatePalette(lpLogPal);

	//释放已分配内存并删除临时对象
	GlobalUnlock(hLogPal);
	GlobalFree(hLogPal);
	ReleaseDC(NULL,hDC);

	//返回
	return hPal;
}

/***********************************************************
* \函数名称:
*         CreateBitmap()
* \输入参数:
*         CDC* pDC            -设备上下文指针
* \返回值:
*         HBITMAP             -到GDI位图的句柄,如果不成功,则为 NULL
*                             -该句柄不是作为公共数据成员存储的
* \说明:
*       从已有的DIB中创建DDB位图
*       不要与CreateSection混淆了,后者的作用是生成DIB并保存句柄
************************************************************
*/
HBITMAP CDib::CreateBitmap(CDC* pDC)
{
	//如果不存在图像数据,则返回NULL
	if(m_dwSizeImage == 0) return NULL;

	//用指定的DIB来创建DDB,并用DIB信息初始化位图的图像位
	HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(),m_lpBMIH,
		CBM_INIT,m_lpImage,(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS);
	ASSERT(hBitmap != NULL);

	//返回DDB位图句柄
	return hBitmap;
}

/***********************************************************
* \函数名称:
*         CreateSection()
* \输入参数:
*         CDC* pDC            -设备上下文指针
* \返回值:
*         HBITMAP             -到GDI位图的句柄,如果不成功,则为 NULL
*                             -该句柄也是作为公共数据成员存储的
* \说明:
*       通过调用Win32 SDK的CreateDIBSection函数创建一个DIB段
*       图像内存将不被初始化
************************************************************
*/
HBITMAP CDib::CreateSection(CDC* pDC/*=NULL*/)
{
	//如果信息头为空,不作任何处理
	if(m_lpBMIH == NULL) return NULL;

	//如果图像数据不存在,不作任何处理
	if(m_lpImage != NULL) return NULL;

	//创建一个DIB段
	m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(),(LPBITMAPINFO)m_lpBMIH,
		DIB_RGB_COLORS,(LPVOID*)&m_lpImage,NULL,0);
	ASSERT(m_lpImage != NULL);

	//返回HBITMAP句柄
	return m_hBitmap;
}

/***********************************************************
* \函数名称:
*         ComputePaletteSize()
* \输入参数:
*         int nBitCount          -像素位数
* \返回值:
*         无
* \说明:
*        根据像素位数计算调色板的尺寸
************************************************************
*/
void CDib::ComputePaletteSize(int nBitCount)
{
	if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0))
	{
		switch(nBitCount)
		{
			case 1:
				m_nColorTableEntries = 2;
				break;
			case 4:
				m_nColorTableEntries = 16;
				break;
			case 8:
				m_nColorTableEntries = 256;
				break;
			case 16:
			case 24:
			case 32:
				m_nColorTableEntries = 0;
				break;
			default:
				ASSERT(FALSE);
		}
	}
	else
	{
		m_nColorTableEntries = m_lpBMIH->biClrUsed;
	}
	ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256)); 
}

/***********************************************************
* \函数名称:
*         ComputeMetrics()
* \输入参数:
*         无          -
* \返回值:
*         无
* \说明:
*       计算调色板和位图的尺寸
************************************************************
*/
void CDib::ComputeMetrics()
{
	if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER))
	{
		TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");
		throw new CException;
	}
	m_dwSizeImage = m_lpBMIH->biSizeImage;
	if(m_dwSizeImage == 0)
	{
		DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32;
		if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32)
		{
			dwBytes++;
		}
		dwBytes *= 4;
		m_dwSizeImage = dwBytes * m_lpBMIH->biHeight; // no compression
	}
	m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);
}

/***********************************************************
* \函数名称:
*         Empty()
* \输入参数:
*         无
* \返回值:
*         无
* \说明:
*       该函数清空DIB,释放已分配的内存
*       必要的时候关于映射文件
************************************************************
*/
void CDib::Empty()
{
	//关闭内存映射文件的连接
	DetachMapFile();

	//根据内存分配状态,调用相应的函数释放信息头
	if(m_nBmihAlloc == crtAlloc) {
		delete [] m_lpBMIH;
	}
	else if(m_nBmihAlloc == heapAlloc) {
		::GlobalUnlock(m_hGlobal);
		::GlobalFree(m_hGlobal);
	}

	//释放图像数据内存
	if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;

	//释放调色板句柄
	if(m_hPalette != NULL) ::DeleteObject(m_hPalette);

	//如果创建了BITMAP,则进行释放
	if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);

	//重新设置内存分配状态
	m_nBmihAlloc = m_nImageAlloc = noAlloc;

	//释放内存后,还需要将指针设置为NULL,相应的数据设置为0
	m_hGlobal = NULL;
	m_lpBMIH = NULL;
	m_lpImage = NULL;
	m_lpvColorTable = NULL;
	m_nColorTableEntries = 0;
	m_dwSizeImage = 0;
	m_lpvFile = NULL;
	m_hMap = NULL;
	m_hFile = NULL;
	m_hBitmap = NULL;
	m_hPalette = NULL;
}
/***********************************************************
* \函数名称:
*         ConvertDDBToDIB()
* \输入参数:
*         HBITMAP hBitmap     -指向源数据的BITMAP句柄
*         CDib* pDibDst       -指向转换目标的CDib对象指针
* \返回值:
*         BOOL                -如果成功,则返回TRUE
* \说明:
*       该函数将源BITMAP类pDibSrc中的数据拷贝到pDibDst中,并对相应的数据成员赋值
************************************************************
*/
BOOL CDib::ConvertDDBToDIB(HBITMAP hBitmap, HPALETTE hPal)
{
	//声明一个BITMAP结构
	BITMAP bm;

	//设备上下文
	HDC hDC;

	//像素位数
	WORD biBitCount;

	//调色板表项数
	int nColorTableEntries;

	//如果hBitmap句柄无效,则返回
	if(!hBitmap)
	{
		return FALSE;
	}
	//释放已分配的内存
	Empty();

	//填充图像数据到bm中,其中最后一个参数表示接收这个指定的对象的指针
	if(!GetObject(hBitmap,sizeof(BITMAP),(LPBYTE)&bm))
	{
		return FALSE;
	}

	//计算像素位数
	biBitCount = bm.bmPlanes * bm.bmBitsPixel;
	if(biBitCount <= 1)
		biBitCount = 1;
	else if(biBitCount <= 4)
		biBitCount = 4;
	else if(biBitCount <= 8)
		biBitCount = 8;
	else
		biBitCount = 24;

	//计算调色板的尺寸
	//如果biClrUsed为零,则用到的颜色数为2的biBitCount次方
	switch(biBitCount)
	{
	case 1:
		nColorTableEntries = 2;
		break;
	case 4:
		nColorTableEntries = 16;
		break;
	case 8:
		nColorTableEntries = 256;
		break;
	case 16:
	case 24:
	case 32:
		nColorTableEntries = 0;
		break;
	default:
		ASSERT(FALSE);
	}
	ASSERT((nColorTableEntries >= 0) && (nColorTableEntries <= 256));
	m_nColorTableEntries = nColorTableEntries;

	//分配DIB信息头和调色板的内存
	m_lpBMIH = (LPBITMAPINFOHEADER) new char
		[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries];
	m_nBmihAlloc = m_nImageAlloc = crtAlloc;
	m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
	m_lpBMIH->biWidth = bm.bmWidth;	
	m_lpBMIH->biHeight = bm.bmHeight;
	m_lpBMIH->biPlanes = 1;
	m_lpBMIH->biBitCount = biBitCount;
	m_lpBMIH->biCompression = BI_RGB;
	m_lpBMIH->biSizeImage = 0;
	m_lpBMIH->biXPelsPerMeter = 0;
	m_lpBMIH->biYPelsPerMeter = 0;
	m_lpBMIH->biClrUsed = nColorTableEntries;
	m_lpBMIH->biClrImportant = nColorTableEntries;

	//获得设备上下文句柄
	hDC = GetDC(NULL);

	//如果没有指定调色板,则从系统中获得当前的系统调色板
	if(hPal == NULL)
	{
		hPal = GetSystemPalette();		
	}
	hPal = SelectPalette(hDC,hPal,FALSE);
	RealizePalette(hDC);

	//调用GetDIBits填充信息头,并获得图像数据的尺寸
	GetDIBits(hDC,hBitmap,0,(UINT)m_lpBMIH->biHeight,NULL,
		(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS);

	//如果没正确的获得图像数据尺寸,则重新计算
	if(m_lpBMIH->biSizeImage == 0)
	{
		m_lpBMIH->biSizeImage = (((bm.bmWidth * biBitCount) + 31)/32*4) * bm.bmHeight;
	}

	//分配存放图像数据的内存
	m_lpImage = (LPBYTE) new char[m_lpBMIH->biSizeImage];

	//调用GetDIBits加载图像数据,给出图像数据指针
	//如果加载不成功,释放内存,返回FALSE
	if(GetDIBits(hDC,hBitmap,0,(UINT)m_lpBMIH->biHeight,(LPBYTE)m_lpImage,
		(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS) == 0)
	{
		Empty();

		SelectPalette(hDC,hPal,TRUE);
		RealizePalette(hDC);
		ReleaseDC(NULL,hDC);

		return FALSE;
	}

	//删除临时变量
	SelectPalette(hDC,hPal,TRUE);
	RealizePalette(hDC);
	ReleaseDC(NULL,hDC);

	return TRUE;
}

⌨️ 快捷键说明

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