www.pudn.com > zhifangtu.rar > DipDoc.cpp


// DipDoc.cpp : implementation of the CDipDoc class 
// 
 
#include "stdafx.h" 
#include "Dip.h" 
 
#include "DipDoc.h" 
#include "MainFrm.h" 
#include "ChildFrm.h" 
#include "DipView.h" 
#include "BmpFileInfo.h" 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CDipDoc 
extern char szFilter[]; 
IMPLEMENT_DYNCREATE(CDipDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CDipDoc, CDocument) 
	//{{AFX_MSG_MAP(CDipDoc) 
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen) 
	ON_COMMAND(ID_FILE_SAVE, OnFileSave) 
	ON_COMMAND(ID_FILE_NEW, OnFileNew) 
	ON_COMMAND(ID_BMPINFO, OnBmpinfo) 
	ON_COMMAND(ID_ZHIFANGTU, OnZhifangtu) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CDipDoc construction/destruction 
 
CDipDoc::CDipDoc() 
{ 
	// TODO: add one-time construction code here 
	m_pImageObject = NULL; 
	m_bImageLoaded = FALSE; 
	m_nZhifang=FALSE; 
} 
 
CDipDoc::~CDipDoc() 
{ 
	if(m_pImageObject != NULL) 
	{ 
		delete m_pImageObject; 
		m_pImageObject = NULL; 
	} 
} 
 
 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDipDoc serialization 
 
void CDipDoc::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		// TODO: add storing code here 
	} 
	else 
	{ 
		// TODO: add loading code here 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CDipDoc diagnostics 
 
#ifdef _DEBUG 
void CDipDoc::AssertValid() const 
{ 
	CDocument::AssertValid(); 
} 
 
void CDipDoc::Dump(CDumpContext& dc) const 
{ 
	CDocument::Dump(dc); 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CDipDoc commands 
 
void CDipDoc::OnFileOpen()  
{ 
	// TODO: Add your command handler code here 
	static int nIndex = 1; 
 
	CFileDialog FileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter ); 
	FileDlg.m_ofn.nFilterIndex = (DWORD)nIndex; 
 
	if( FileDlg.DoModal() == IDOK ) 
	{ 
		CString strPathName = FileDlg.GetPathName(); 
		AfxGetApp()->OpenDocumentFile(strPathName); 
		nIndex = (int) FileDlg.m_ofn.nFilterIndex; 
		if(!LoadImageToDocument()) 
		{ 
			AfxMessageBox("无法载入图像文件!"); 
			return; 
		} 
	} 
} 
 
void CDipDoc::OnFileSave()  
{ 
	// TODO: Add your command handler code here 
	static int nIndex = 1; 
	 
	CFileDialog DialogSaveAs( FALSE, NULL, m_pImageObject->GetImageName(), 
		OFN_HIDEREADONLY, szFilter ); 
	 
	DialogSaveAs.m_ofn.nFilterIndex = (DWORD) nIndex; 
	 
	if( DialogSaveAs.DoModal() == IDOK ) 
	{ 
		 
		CMainFrame *pMainFrame = ( CMainFrame *  )AfxGetMainWnd(); 
		CChildFrame *pChildFrame = ( CChildFrame * )pMainFrame->MDIGetActive(); 
		CDipView *pDipView = ( CDipView * )pChildFrame->GetActiveView(); 
		 
		nIndex = (int) DialogSaveAs.m_ofn.nFilterIndex; 
		if( nIndex == 5 ) 
		{ 
			 
			if( m_pImageObject->GetNumBits() != 24 ) 
			{ 
				 
				AfxMessageBox("必须是24位真彩色图像才能存为JPEG格式!"); 
				return; 
				 
			} 
			 
		} 
		 
		if( m_pImageObject != NULL ) 
		{ 
			 
			CString strPathName = DialogSaveAs.GetPathName(); 
			int nFindIndex = strPathName.Find("."); 
			if( nFindIndex != -1) 
				strPathName = strPathName.Left( nFindIndex ); 
			strPathName += CImageObject::szExtensions[ nIndex - 1 ]; 
			m_pImageObject->Save( strPathName ); 
			 
			CString strFileName = DialogSaveAs.GetFileName(); 
			nFindIndex = strFileName.Find("."); 
			if ( nFindIndex != -1 ) 
				strFileName = strFileName.Left( nFindIndex ); 
			strFileName += CImageObject::szExtensions[ nIndex - 1 ]; 
			pChildFrame->SetWindowText( strFileName ); 
			 
			SetPathName( strPathName ); 
			if( nIndex == 5 ) 
			{ 
				 
				m_pImageObject->Load( strPathName ); 
				pDipView->InvalidateRect( NULL, FALSE ); 
				pDipView->UpdateWindow(); 
				 
			} 
			 
		} 
		 
	} 
 
	 
} 
BOOL CDipDoc::LoadImageToDocument() 
{ 
	CString strPathName = GetPathName(); 
	//设置等待光标 
	BeginWaitCursor(); 
	m_pImageObject = new CImageObject( strPathName.GetBuffer(3) ); 
	//取消等待光标 
	EndWaitCursor(); 
	//读入图像文件失败 
	if( m_pImageObject == NULL ) 
	{ 
		AfxMessageBox("无法创建图像类对象!"); 
		//返回FALSE 
		return(FALSE); 
	} 
	//读入图像文件成功,设置相应变量 
	m_bImageLoaded = TRUE; 
	//返回TRUE 
	return(TRUE); 
} 
 
void CDipDoc::OnFileNew()  
{ 
	// TODO: Add your command handler code here 
} 
 
void CDipDoc::OnBmpinfo()  
{ 
	// TODO: Add your command handler code here 
	CBmpFileInfo bmpFile1; 
	bmpFile1.m_nFileSize=m_pImageObject->GetFileSize(); 
	bmpFile1.m_biBitCount=m_pImageObject->GetNumBits(); 
	bmpFile1.m_biHeight=m_pImageObject->GetHeight(); 
	bmpFile1.m_biWidth=m_pImageObject->GetWidth(); 
	bmpFile1.DoModal(); 
} 
 
BOOL CDipDoc::OnZhifangtu()  
{ 
	// TODO: Add your command handler code here 
	//若未指定m_pImageObject对象指针返回FALSE 
	if(m_pImageObject== NULL ) return( FALSE ); 
 
	//只处理8位图像 
	if(m_pImageObject->GetNumBits() != 8)  
	{ 
		AfxMessageBox("目前只支持8位灰度图像的处理!"); 
		return( FALSE ); 
	} 
	 
	//定义变量 
	unsigned char *pBuffer, *pBits, *pTemp; 
	BITMAPINFOHEADER *pBIH; 
	RGBQUAD *pPalette; 
	int nWidthBytes, nNumColors, x, y; 
 
	int nWidth = m_pImageObject->GetWidth(); 
	int nHeight = m_pImageObject->GetHeight(); 
 
	//pBuffer: 获得位图数据指针 
	pBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes,  
											m_pImageObject->GetNumBits() ); 
	if( pBuffer == NULL ) return( FALSE ); 
 
	//pBIH:获得位图信息头地址 
	pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)]; 
	//nNumColors:获得调色板中的颜色数。图像为16位色或更高时为0 
	nNumColors = m_pImageObject->GetNumColors(); 
	//pPalette:获得调色板数据地址 
	pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)]; 
	//pBits:获得位图数据地址 
	pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ 
										nNumColors*sizeof(RGBQUAD)]; 
	// 创建直方图数据 
	int *pHistogram = GetHistogram(); 
	// 灰度映射表 
	BYTE bMap[256]; 
	int i, j; 
	for(i = 0; i < 256; i++) 
	{ 
		bMap[i] = 0; 
	} 
	// 计算灰度映射表 
	for (i = 0; i < 256; i++) 
	{ 
		// 初始为0 
		long lTemp = 0; 
		for (j = 0; j <= i ; j++) 
		{ 
			lTemp += pHistogram[j]; 
		} 
		// 计算对应的新灰度值 
		bMap[i] = (BYTE) (lTemp*255/nHeight/nWidth); 
	} 
	delete [] pHistogram; 
	for(y = 0; y < nHeight; y++) 
	{ 
		pTemp = pBits; 
		pTemp += y * nWidthBytes;	//位图数据下一行起始指针 
		for(x = 0; x < nWidth; x++) 
		{ 
			long lpSrc = pTemp[x]; 
			// 计算新的灰度值 
			pTemp[x] = bMap[lpSrc];			 
		} 
	} 
	::GlobalUnlock(m_pImageObject->GetDib()); 
	BeginWaitCursor(); 
	UpdateAllViews(NULL); 
	EndWaitCursor(); 
	return TRUE; 
} 
int *CDipDoc::GetHistogram(int nX1,int nY1,int nX2,	int nY2,CImageObject *pDibObject) 
{ 
	//使用传入的CDibObject对象 
	if( pDibObject != NULL ) m_pImageObject = pDibObject; 
	//无CDibObject对象, 返回FALSE 
	if( m_pImageObject == NULL ) return( FALSE ); 
	//坐标规整化 
	m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 ); 
	//定义变量 
	unsigned char *pBuffer, *pBits; 
	RGBQUAD *pPalette; 
	int nWidthBytes, nNumColors; 
	//获得图像指针 
	pBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() ); 
	if( pBuffer == NULL ) return( NULL ); 
	//获得颜色数 
	nNumColors = m_pImageObject->GetNumColors(); 
	//获得调色板指针 
	pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)]; 
	//获得位图数据指针 
	pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)]; 
	//创建直方图数据 
	int *nHistogramBuffer = CreateHistogram( nX1, nY1, nX2, nY2, pBits, pPalette, nWidthBytes ); 
	::GlobalUnlock( m_pImageObject->GetDib() ); 
	return( nHistogramBuffer ); 
} 
int *CDipDoc::CreateHistogram(int nX1,int nY1,int nX2,int nY2,  
							  unsigned char *pData, RGBQUAD *pPalette,  
							  int nWidthBytes, CImageObject *pDibObject ) 
{ 
	//图像指针为空,无法操作返回 
	if( pDibObject != NULL )m_pImageObject= pDibObject; 
	if( m_pImageObject== NULL ) return( FALSE ); 
	//分配直方图数据缓存区(数组) 
	int *pBuffer = new int [256 * 4]; 
	//分配直方图数据缓存区失败 
	if( pBuffer == NULL ) return( NULL ); 
	//直方图数据缓存区清零 
	memset( pBuffer, 0, ( 256 * 4) * sizeof( int ) ); 
	//变量定义 
	DWORD dwGray; 
	int x, y; 
	unsigned char *pTemp, ucRed, ucGreen, ucBlue; 
	//图像的高度 
	int nHeight =m_pImageObject->GetHeight(); 
	switch(m_pImageObject->GetNumBits() ) 
	{ 
	case 1:				//每像素位数为1,不处理 
		break; 
	case 4:				//每像素位数为4,不处理 
		break; 
	case 8:				//每像素位数为8		 
		for( y = nY1; y <= nY2; y++ ) 
		{ 
			//数据指针定位到图像数据起始位置 
			pTemp = pData; 
			//数据指针定位到图像数据每行的起始零位置 
			pTemp += ( ( nHeight - 1 - y ) * nWidthBytes ); 
			//数据指针定位到图像数据每行的起始nX1位置 
			pTemp += nX1; 
			for( x = nX1; x <= nX2; x++ ) 
			{ 
				//pTemp[x]为当前像素值,它为调色板项的索引值, 
				//以此为索引,取出调色板项的相应红绿蓝分量值。 
				ucRed   = pPalette[pTemp[x]].rgbRed; 
				ucGreen = pPalette[pTemp[x]].rgbGreen; 
				ucBlue  = pPalette[pTemp[x]].rgbBlue; 
 
				//按关系L=0.3R+0.59G+0.11B,得到亮度值 
				dwGray  = ( (DWORD) ucRed * 30 + 
					        (DWORD) ucGreen * 59 + 
					        (DWORD) ucBlue * 11 ) / 100; 
				dwGray &= 0x000000ff; 
 
				//亮度直方图数据 
				pBuffer[dwGray]++; 
				//红色直方图数据 
				pBuffer[256 + ucRed]++; 
				//绿色直方图数据 
				pBuffer[512 + ucGreen]++; 
				//蓝色直方图数据 
				pBuffer[768 + ucBlue]++; 
 
			} 
		} 
		break; 
	case 16:				//每像素位数为16 
		for( y = nY1; y <= nY2; y++ ) 
		{ 
			//数据指针定位到图像数据起始位置 
			pTemp = pData; 
			//数据指针定位到图像数据每行的起始零位置 
			pTemp += ( ( nHeight - 1 - y ) * nWidthBytes ); 
			//数据指针定位到图像数据每行的起始nX1位置 
			pTemp += ( nX1 * 2 ); 
			for( x = nX1; x <= nX2; x++ ) 
			{ 
				//获取三原色分量 
				GETRGB555( ucRed, ucGreen, ucBlue, pTemp ); 
				//按关系L=0.3R+0.59G+0.11B,得到亮度值 
				dwGray = ( (DWORD) ucRed * 30 + 
					       (DWORD) ucGreen * 59 + 
					       (DWORD) ucBlue * 11 ) / 100; 
				dwGray &= 0x000000ff; 
				//亮度直方图数据 
				pBuffer[dwGray]++; 
				//红色直方图数据 
				pBuffer[256 + ucRed]++; 
				//绿色直方图数据 
				pBuffer[512 + ucGreen]++; 
				//蓝色直方图数据 
				pBuffer[768 + ucBlue]++; 
				//数据指针加2 
				pTemp += 2; 
			} 
		} 
		break; 
	case 24:				//每像素位数为24 
		for( y = nY1; y < nY2; y++ ) 
		{ 
			//数据指针定位到图像数据起始位置 
			pTemp = pData; 
			//数据指针定位到图像数据每行的起始零位置 
			pTemp += ( ( nHeight - 1 - y ) * nWidthBytes ); 
			//数据指针定位到图像数据每行的起始nX1位置 
			pTemp += ( nX1 * 3 ); 
			for( x=nX1; x<=nX2; x++ ) 
			{ 
				//获取像素颜色的三原色。 
				ucRed   = pTemp[x * 3 + 2]; 
				ucGreen = pTemp[x * 3 + 1]; 
				ucBlue  = pTemp[x * 3]; 
 
				//按关系L=0.3R+0.59G+0.11B,得到亮度值 
				dwGray  = ( (DWORD) ucRed * 30 + 
					        (DWORD) ucGreen * 59 + 
					        (DWORD) ucBlue * 11 ) / 100; 
				dwGray &= 0x000000ff; 
				//亮度直方图数据 
				pBuffer[dwGray]++; 
				//红色直方图数据 
				pBuffer[256 + ucRed]++; 
				//绿色直方图数据 
				pBuffer[512 + ucGreen]++; 
				//蓝色直方图数据 
				pBuffer[768 + ucBlue]++; 
				//数据指针加3 
				pTemp += 3; 
			} 
		} 
		break; 
	case 32:				//每像素位数为24 
		for( y = nY1; y <= nY2; y++ ) 
		{ 
			//数据指针定位到图像数据起始位置 
			pTemp = pData; 
			//数据指针定位到图像数据每行的起始零位置 
			pTemp += ( ( nHeight - 1 - y ) * nWidthBytes ); 
			//数据指针定位到图像数据每行的起始nX1位置 
			pTemp += ( nX1 * 4 ); 
 
			for( x = nX1; x <= nX2; x++ ) 
			{ 
				//获取像素颜色的三原色。 
				GETRGB888( ucRed, ucGreen, ucBlue, pTemp ); 
 
				//按关系L=0.3R+0.59G+0.11B,得到亮度值 
				dwGray = ( (DWORD) ucRed * 30 + 
					       (DWORD) ucGreen * 59 + 
					       (DWORD) ucBlue * 11 ) / 100; 
 
				dwGray &= 0x000000ff; 
				//亮度直方图数据 
				pBuffer[dwGray]++; 
				//红色直方图数据 
				pBuffer[256 + ucRed]++; 
				//绿色直方图数据 
				pBuffer[512 + ucGreen]++; 
				//蓝色直方图数据 
				pBuffer[768 + ucBlue]++; 
 
				pTemp += 4; 
			} 
		} 
		break; 
	} 
	return( pBuffer ); 
}