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

📄 dib.cpp

📁 读入图像序列
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DIB.cpp: implementation of the CDIB class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Test.h"
#include "DIB.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDIB::CDIB()
{
	m_hDIB=NULL;
	m_sizeDIB=CSize(0,0);
	m_pPal=NULL;
}

CDIB::~CDIB()
{
	if(m_hDIB!=NULL)//删除存储图像的区域
		::GlobalFree((HGLOBAL)m_hDIB);
	if(m_pPal!=NULL)
		delete m_pPal;
}

CDIB::CDIB(LPCTSTR lpPathName)
{

	m_hDIB=CreateDIB(lpPathName);
	if(m_hDIB==NULL)
	{
		MessageBox(NULL,"构造DIB类失败!",NULL,MB_OK);
		m_sizeDIB=CSize(0,0);
		m_pPal=NULL;
	}
	else
	{
		LPSTR _lpDIB=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
		m_sizeDIB=GetDIBSize(_lpDIB);
		::GlobalUnlock((HGLOBAL)m_hDIB);
		m_pPal=new CPalette;
		//if(!CreateDIBPalette(m_hDIB,m_pPal))
		//{
		//	delete m_pPal; m_pPal=NULL;
		//}
		CreateDIBPalette(m_hDIB,m_pPal);
		delete m_pPal; m_pPal=NULL;
	}
}

HDIB CDIB::ReadDIBFile(CFile& file)
{
	BITMAPFILEHEADER bmfHeader;
	DWORD dwBitsSize;
	HDIB hDIB;
	LPSTR pDIB;
	dwBitsSize=file.GetLength();
	if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
	{return NULL;}
    if(bmfHeader.bfType!=DIB_HEADER_MARKER)
	{return NULL;}
	hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize-sizeof(BITMAPFILEHEADER));
	if(hDIB==0)
		return NULL;
	pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
	{
		::GlobalUnlock((HGLOBAL)hDIB);
		::GlobalFree((HGLOBAL)hDIB);
		return NULL;
	}
	::GlobalUnlock((HGLOBAL)hDIB);
	return hDIB;
}

HDIB CDIB::CreateDIB(LPCTSTR lpPathName)
{
	HDIB _hDIB;
	CFile file;
	CFileException fe;
	if(!file.Open(lpPathName,CFile::modeRead|CFile::shareDenyWrite,&fe))
	{
	//	ReportSaveLoadException(lpPathName,&fe,FALSE,AFX_IDP_FAILED_TO_OPEN_DOC);
		//_hDIB=NULL;
		return NULL;
	}
	TRY{
		_hDIB=ReadDIBFile(file);
	}
	CATCH(CFileException,eLoad)
	{
		file.Abort();
		_hDIB=NULL;
	//	return ;
	}
	END_CATCH
	return _hDIB;
}

CSize CDIB::GetDIBSize(LPSTR lpDIB)
{
	LPBITMAPINFOHEADER lpbmi;
	LPBITMAPCOREHEADER lpbmc;
	lpbmi=(LPBITMAPINFOHEADER)lpDIB;
	lpbmc=(LPBITMAPCOREHEADER)lpDIB;
	if(IS_WIN30_DIB(lpDIB))
	{
		return CSize((int)lpbmi->biWidth,(int)lpbmi->biHeight);	
	}
	else
	{
		return CSize((int)lpbmc->bcWidth,(int)lpbmc->bcHeight);
	}
}

WORD CDIB::NumColors(LPSTR lpbi)
{
	WORD wBitCount;
	WORD wNumCol;
	if(IS_WIN30_DIB(lpbi))
	{
		DWORD dwClrUsed;
		dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
		if(dwClrUsed!=0)
			return (WORD)dwClrUsed;
	}

		if(IS_WIN30_DIB(lpbi))
			wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
		else
			wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
		switch(wBitCount)
		{
		case 1:
			wNumCol=2;
			break;
		case 4:
			wNumCol=16;
			break;
		case 8:
			wNumCol=256;
			break;
		default:
			wNumCol=0;		
		}
		return wNumCol;
}

BOOL CDIB::CreateDIBPalette(HDIB hDIB, CPalette *cPal)
{
	LPLOGPALETTE lpPal;//指针,指向逻辑调色板
	HANDLE hLogPal;//调色板句柄
	int i;
	WORD wNumColors;
	LPSTR lpbi;//DIB指针
	LPBITMAPINFO lpbmi;//BITMAPINFO结构指针,书中好像没有介绍这个结构,可以直接把DIB对象的指针赋给它
	LPBITMAPCOREINFO lpbmc;
	BOOL bResult=FALSE;
	if(hDIB==NULL)
		return FALSE;
	lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	lpbmi=(LPBITMAPINFO)lpbi;
	lpbmc=(LPBITMAPCOREINFO)lpbi;
	wNumColors=NumColors(lpbi);
	if(wNumColors!=0){
		hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
		if(hLogPal==0)
		{
			::GlobalUnlock((HGLOBAL)hDIB);
			return FALSE;		
		}
		lpPal=(LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
		lpPal->palVersion=PALVERSION;
		lpPal->palNumEntries=(WORD)wNumColors;
		if(IS_WIN30_DIB(lpbi)){
			for(i=0;i<(int)wNumColors;i++){
				lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
				lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
				lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
				lpPal->palPalEntry[i].peFlags=0;			
			}
		}
		else{
			for(i=0;i<(int)wNumColors;i++){
				lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
				lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
				lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
				lpPal->palPalEntry[i].peFlags=0;			
			}
		}//end else
		bResult=cPal->CreatePalette(lpPal);
		::GlobalUnlock((HGLOBAL)hLogPal);
		::GlobalFree((HGLOBAL)hLogPal);	
	}
	::GlobalUnlock((HGLOBAL)hDIB);
	return bResult;
}

HDIB CDIB::GetHDIB() const
{
	return m_hDIB;
}

BOOL CDIB::PaintDIB(HDC hDC, LPRECT lpDCRect)
{
 CRect rcDIB;
 rcDIB.left=0; rcDIB.top=0; rcDIB.right=m_sizeDIB.cx; rcDIB.bottom=m_sizeDIB.cy;
 BOOL bSuccess=FALSE;
 LPSTR lpDIBHdr; //信息头
 LPSTR lpDIBBits; //图像起始位置
 HPALETTE hPal=NULL;//DIB调色板句柄
 HPALETTE hOldPal=NULL;
 if(m_hDIB==NULL)
	 return FALSE;
 lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
 lpDIBBits=FindDIBBits(lpDIBHdr);
 if(m_pPal!=NULL)
 {
	 hPal=(HPALETTE)m_pPal->m_hObject;
	 hOldPal=::SelectPalette(hDC,hPal,TRUE);//全局函数,将当前环境hDC赋予新的调色板,并返回以前的调色板 
 }
 ::SetStretchBltMode(hDC,COLORONCOLOR);
 if((RECTWIDTH(lpDCRect)==m_sizeDIB.cx)&&(RECTHEIGHT(lpDCRect)==m_sizeDIB.cy))//目标区域和源区域相同,调用全局函数SetDIBitsToDevice
	 bSuccess=::SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),rcDIB.left,rcDIB.top,0,m_sizeDIB.cy,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
 else //目标区域与源区域不同时,进行缩放,调用全局函数StretchDIBits
	 bSuccess=::StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),rcDIB.left,rcDIB.top,m_sizeDIB.cx,m_sizeDIB.cy,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
 ::GlobalUnlock((HGLOBAL)m_hDIB);
 if(hOldPal!=NULL)
	 ::SelectPalette(hDC,hOldPal,TRUE);
 
 return bSuccess;
}

//计算DIB对象的象素的起始位置,并返回其指针
LPSTR CDIB::FindDIBBits(LPSTR lpbi)
{
	return (lpbi+*(LPWORD)lpbi+PaletteSize(lpbi));//*(LPWORD)lpbi为信息头的一个元素,即biSize,表示本信息头的长度
}

WORD CDIB::PaletteSize(LPSTR lpbi)
{
	if(IS_WIN30_DIB(lpbi)){
		return (WORD)(NumColors(lpbi)*sizeof(RGBQUAD));
	}
	else{
		return (WORD)(NumColors(lpbi)*sizeof(RGBTRIPLE));
	}
}

CSize CDIB::GetDIBSize()
{
	return m_sizeDIB;
}

//根据pDIB及其中的一个子区域构造一个子图像类
CDIB::CDIB(CDIB* pDIB, int _left, int _top, int _right, int _bottom)
{
	int _width,_height,i,j,m,n;
	_width=_right-_left;
	_height=_bottom-_top;
	int _widthBytes=WIDTHBYTES(8*_width);
	int srcWidth=pDIB->GetDIBSize().cx;
	int srcHeight=pDIB->GetDIBSize().cy;
	int srcwidthBytes=WIDTHBYTES(8*srcWidth);
	LPSTR lpbi,destLpbi;
	unsigned char* destImage, * srcImage;
	LPBITMAPINFOHEADER lpbmi,destLpbmi;
	HDIB _hDIB;

	if(!((_left>=0)&&(_right<=srcWidth)&&(_top>=0)&&(_bottom<=srcHeight)))
	{
		MessageBox(NULL,"子图像的边界定义出错!",NULL,MB_OK);
		SetEmpty();
		return;
	}

	_hDIB=pDIB->GetHDIB();
	lpbi=(LPSTR)::GlobalLock((HGLOBAL)_hDIB);
	if(NumColors(lpbi)!=256)//仅支持对256色位图提取子位图
	{
		MessageBox(NULL,"仅支持256位图!",NULL,MB_OK);
		::GlobalUnlock((HGLOBAL)_hDIB);
		SetEmpty();
		return;
	}
	if(!IS_WIN30_DIB(lpbi))
	{
		MessageBox(NULL,"仅支持WIN30位图!",NULL,MB_OK);
		::GlobalUnlock((HGLOBAL)_hDIB);
		SetEmpty();
		return;
	}
	WORD _paletteSize=pDIB->PaletteSize(lpbi);
//	m_hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(BITMAPINFOHEADER)+_paletteSize+_widthBytes*_height);
	m_hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,*(LPWORD)lpbi+_paletteSize+_widthBytes*_height);
	if(m_hDIB==NULL)
	{
		::GlobalUnlock((HGLOBAL)_hDIB);
		SetEmpty();
		return;
	}
	destLpbi=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
	::memcpy(destLpbi,lpbi,sizeof(BITMAPINFOHEADER)+_paletteSize);
	destLpbmi=(LPBITMAPINFOHEADER)destLpbi;
	lpbmi=(LPBITMAPINFOHEADER)lpbi;
	destLpbmi->biBitCount=8;
	destLpbmi->biClrUsed=256;
	destLpbmi->biHeight=_height;
	destLpbmi->biWidth=_width;
	destLpbmi->biSizeImage=_widthBytes*_height;
	destImage=(unsigned char*)FindDIBBits(destLpbi);
	srcImage=(unsigned char*)FindDIBBits(lpbi);
	for(j=_top,n=_height-1;j<_bottom;j++,n--)
		for(i=_left,m=0;i<_right;i++,m++)

⌨️ 快捷键说明

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