www.pudn.com > yuzhishuanfa.zip > ImageView.cpp


// ImageView.cpp : implementation file 
// 
#include "afxwin.h" 
#include "stdafx.h" 
#include "ImageView.h" 
#include "ImageDoc.h" 
 
#include   
#include   
 
#include "resource.h" 
 
#include "AppUtil.h" 
#include "progdlg.h" 
#include "Histogram.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define IMAGEA 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA 
 
IMPLEMENT_DYNCREATE(CImageViewA, CScrollView) 
 
BEGIN_MESSAGE_MAP(CImageViewA, CScrollView) 
	//{{AFX_MSG_MAP(CImageViewA) 
	ON_COMMAND(ID_EDIT_CLEAR, OnEditClear) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear) 
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy) 
	ON_COMMAND(ID_EDIT_CUT, OnEditCut) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut) 
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste) 
	ON_COMMAND(ID_EDIT_REDO, OnEditRedo) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo) 
	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) 
	ON_COMMAND(ID_COLOR_NEGATIVE, OnColorNegative) 
	ON_UPDATE_COMMAND_UI(ID_COLOR_NEGATIVE, OnUpdateColorNegative) 
	ON_COMMAND(ID_MENUITEMPENGZHANG, OnMenuitemPENGZHANG) 
	ON_COMMAND(ID_MENUITEMFUSHI, OnMenuitemFUSHI) 
	ON_COMMAND(ID_MENUITEMSUB, OnMenuitemSUB) 
	ON_COMMAND(ID_MENUITEMTHILEV, OnMenuitemTHILEV) 
	ON_COMMAND(ID_MENUITEMBILEVEL, OnMenuitembilevel) 
	ON_COMMAND(ID_MENUITEMTWOL, OnMenuitemtwol) 
	ON_COMMAND(ID_FILE_PRINT, OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview) 
	ON_COMMAND(ID_CONCAVE, OnConcave) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
 
CImageViewA::CImageViewA() 
{ 
//	m_nAutoCommand=NULL; 
//	m_bAutoProcessing=FALSE; 
//	m_nRegionCombineMode=RGN_COPY; 
//	m_nRegionFillMode=WINDING; 
	m_nZoomFactor=100; //100% 
//	m_nMouseFunction=MOUSE_REGION; 
//    m_nRegionTool=RGNMARK_FREEHAND; 
	m_HandleForUndo=NULL; 
    m_HandleForRedo=NULL; 
 
	m_pInitImage = NULL; 
	m_pRecoImage = NULL; 
} 
 
 
CImageViewA::~CImageViewA() 
{ 
//	m_Region.Clear(); 
	if (m_HandleForUndo != NULL) 
	{ 
		::GlobalFree(m_HandleForUndo); 
	} 
	if (m_HandleForRedo != NULL) 
	{ 
		::GlobalFree(m_HandleForRedo); 
	} 
//	m_Region.DeleteObject(); 
	if(m_pInitImage) 
	{ 
		delete m_pInitImage; 
		m_pInitImage = NULL; 
	} 
	if(m_pRecoImage) 
	{ 
		delete m_pRecoImage; 
		m_pRecoImage = NULL; 
	} 
 
} 
 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA diagnostics 
 
#ifdef _DEBUG 
void CImageViewA::AssertValid() const 
{ 
	CScrollView::AssertValid(); 
} 
 
void CImageViewA::Dump(CDumpContext& dc) const 
{ 
	CScrollView::Dump(dc); 
} 
 
CImageDocA* CImageViewA::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageDocA))); 
	return (CImageDocA*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA message handlers 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA 绘制 
void CImageViewA::OnInitialUpdate() 
{ 
	CScrollView::OnInitialUpdate(); 
	ASSERT(GetDocument() != NULL); 
 
	// TODO: calculate the total size of this view 
    CSize size=GetDocument()->GetDocSize(); 
	SetScrollSizes(MM_TEXT, size); 
 
	BackUp(); 
 
} 
 
void CImageViewA::OnDraw(CDC* pDC)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	ASSERT_VALID(pDC); 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	HDIB hDIB = pDoc->GetHDIB(); 
 
	//1998.12.26设置背景色 
	pDC->SetBkColor(RGB(255,255,255)); 
	CBrush brush(HS_DIAGCROSS,RGB(192,192,192) ); 
	CRect rectWnd; 
	GetClientRect(&rectWnd); 
	rectWnd.right*=5;rectWnd.bottom*=5;//暂时用此下策 
	pDC->FillRect(&rectWnd,&brush); 
 
	if (hDIB != NULL) 
	{ 
		//由句柄取得位图指针	 
		LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
	 
		//由句柄取得位图宽高	 
		int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x 
		int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y 
		 
		::GlobalUnlock((HGLOBAL) hDIB); 
		 
 
		//确定显示区域大小 
		CRect rcDIB; 
		rcDIB.top = rcDIB.left = 0; 
		rcDIB.right = cxDIB; 
		rcDIB.bottom = cyDIB; 
		CRect rcDest; 
		 
	 
		if (pDC->IsPrinting())   // printer DC 
		{ 
			// 取得打印机纸张大小(in pixels) 
			int cxPage = pDC->GetDeviceCaps(HORZRES); 
			int cyPage = pDC->GetDeviceCaps(VERTRES); 
			// 取得打印机 pixels per inch 
			int cxInch = pDC->GetDeviceCaps(LOGPIXELSX); 
			int cyInch = pDC->GetDeviceCaps(LOGPIXELSY); 
 
			// 
			// Best Fit case -- create a rectangle which preserves 
			// the DIB's aspect ratio, and fills the page horizontally. 
			// 
			// The formula in the "->bottom" field below calculates the Y 
			// position of the printed bitmap, based on the size of the 
			// bitmap, the width of the page, and the relative size of 
			// a printed pixel (cyInch / cxInch). 
			// 
			rcDest.top = rcDest.left = 0; 
			rcDest.bottom = (int)(((double)cyDIB * cxPage * cyInch) 
					/ ((double)cxDIB * cxInch)); 
			rcDest.right = cxPage; 
		} 
		else   // not printer DC 
		{ 
			rcDest = rcDIB; 
			//{{  图象缩放显示 
		    rcDest.bottom=int(rcDest.bottom * m_nZoomFactor/100);     
			rcDest.right =int(rcDest.right *  m_nZoomFactor/100);  
			//}} 
		} 
		 
		//显示 
	    pDC->FillRect(&rcDest,&brush); 
		::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(), 
			&rcDIB, pDoc->GetDocPalette()); 
	} 
} 
//通用处理开始函数 
//操作    :设置m_entryImage,设置等待光标,准备Undo 
//返回值   TRUE  成功 
//         FALSE 失败 
BOOL CImageViewA::BeginProcessing() 
{ 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	m_entryImage.hDIB=NULL;					//源位图句柄 
	m_entryImage.hNewDIB=NULL;				//生成目标位图句柄 
	m_entryImage.pImage=NULL;				//源位图数据开始位(用于灰度图) 
	m_entryImage.pNewImage=NULL;			//目标位图数据开始位(用于灰度图) 
	m_entryImage.hBitmap=NULL;				//源临时中间设备相关位图句柄 
	m_entryImage.hNewBitmap=NULL;			//目标临时中间设备相关位图句柄 
	m_entryImage.hMemDC=NULL;				//源位图设备 
	m_entryImage.hNewDC=NULL;				//目标位图设备 
	m_entryImage.rectImage=CRect(0,0,1,1);		//包围选中区域的最小矩形 
	m_entryImage.sizeImage=CSize(1,1);		//图象大小 
 
	if(pDoc->GetHDIB()==NULL) return FALSE; 
#ifdef IMAGEA  //学习版 
	m_entryImage.rectImage=CRect(0,0, 
		pDoc->GetDocSize().cx,pDoc->GetDocSize().cy); 
#else    
	//求出包围区域的最小矩形 
	if(m_Region.m_hObject == NULL ) return FALSE; 
	m_Region.GetRgnBox(&(m_entryImage.rectImage)); 
	if(m_entryImage.rectImage.right-2<=m_entryImage.rectImage.left || 
		m_entryImage.rectImage.bottom-2<=m_entryImage.rectImage.top) 
	{ 
		AfxMessageBox(_T("选定的处理区域无效")); 
		return FALSE; 
	} 
 
#endif 
	BeginWaitCursor(); 
	ReplaceHandleForUndo((HGLOBAL)pDoc->GetHDIB()); 
 
	m_entryImage.sizeImage.cx=pDoc->GetDocSize().cx; 
	m_entryImage.sizeImage.cy=pDoc->GetDocSize().cy; 
	return TRUE; 
} 
/////////////////////////////////////////////////// 
//灰度处理开始函数 
//返回值   TRUE  成功 
//         FALSE 失败 
//         pNewImage是pImage的副本 
/////////////////////////////////////////////////// 
BOOL CImageViewA::BeginProcessingGray() 
{ 
 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	BeginProcessing(); 
	 
	LPBITMAPINFOHEADER  lpBi,lpNewBi; 
 
	m_entryImage.hDIB=pDoc->GetHDIB(); 
	lpBi=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)	m_entryImage.hDIB);//取得原有位图 
	m_entryImage.pImage=(BYTE FAR*)::FindDIBBits((LPSTR)lpBi); 
 
	m_entryImage.hNewDIB=(HDIB)::CopyHandle((HGLOBAL)m_entryImage.hDIB);//建立一个新位图 
	lpNewBi=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)m_entryImage.hNewDIB); 
	m_entryImage.pNewImage=(BYTE FAR*)::FindDIBBits((LPSTR)lpNewBi); 
	return TRUE; 
} 
/////////////////////////////////////////////////// 
//彩色处理开始函数 
//返回值   TRUE  成功 
//         FALSE 失败 
//         hNewBitmap是hBitmap的副本 
//         hNewDC关联hNewBitmap, hMemDC关联hBitmap 
 
BOOL CImageViewA::BeginProcessingColor() 
{ 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	BeginProcessing(); 
	 
	HDC hDC=::GetDC(NULL); 
	m_entryImage.hMemDC=::CreateCompatibleDC(hDC); 
	m_entryImage.hNewDC=::CreateCompatibleDC(hDC); 
	 
	m_entryImage.hBitmap=::DIBToBitmap(pDoc->GetHDIB(),  
		//HPALETTE(pDoc->GetDocPalette()->m_hObject)); 
		NULL); 
	m_entryImage.hNewBitmap=::DIBToBitmap(pDoc->GetHDIB(), 
		//HPALETTE(pDoc->GetDocPalette()->m_hObject)); 
		NULL); 
/*	//{{test 
	m_entryImage.hBitmap=(HBITMAP)::CopyHandle(pDoc->GetHDIB()); 
	m_entryImage.hNewBitmap=(HBITMAP)::CopyHandle(pDoc->GetHDIB());//建立一个新位图 
	//}} 
*/ 
	if(!m_entryImage.hBitmap || !m_entryImage.hNewBitmap) return FALSE; 
	if(!::SelectObject(m_entryImage.hMemDC,m_entryImage.hBitmap))	return FALSE; 
	if(!::SelectObject(m_entryImage.hNewDC,m_entryImage.hNewBitmap)) return FALSE; 
 
	::DeleteDC(hDC); 
 
	return TRUE; 
} 
 
BOOL CImageViewA::EndProcessing() 
{ 
	UpdateDocument(m_entryImage.hNewDIB); 
	EndWaitCursor(); 
	return TRUE; 
} 
 
BOOL CImageViewA::EndProcessingGray() 
{ 
	::GlobalUnlock((HGLOBAL)m_entryImage.hDIB); 
	::GlobalUnlock((HGLOBAL)m_entryImage.hNewDIB); 
	return EndProcessing(); 
} 
 
BOOL CImageViewA::EndProcessingColor() 
{ 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	m_entryImage.hNewDIB=::BitmapToDIB(m_entryImage.hNewBitmap,  
		//HPALETTE(pDoc->GetDocPalette()->m_hObject));// 使用文档的调色板 
		NULL); 
//	m_entryImage.hNewDIB=(HDIB)::CopyHandle(m_entryImage.hNewBitmap);						   
	BOOL bSuccess=FALSE; 
	if(m_entryImage.hNewDIB!=NULL)	 
	{ 
		bSuccess=EndProcessing(); 
	} 
	else 
	{ 
		EndWaitCursor(); 
	} 
 
	::DeleteDC(m_entryImage.hMemDC); 
	::DeleteDC(m_entryImage.hNewDC); 
	::DeleteObject(m_entryImage.hBitmap); 
	::DeleteObject(m_entryImage.hNewBitmap); 
	::DeleteObject(m_entryImage.hNewDIB); 
	return bSuccess; 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA 剪贴板 
 
void CImageViewA::OnEditClear()  
{ 
	if (OpenClipboard()) 
	{ 
		EmptyClipboard(); 
		CloseClipboard(); 
	} 
	 
} 
 
void CImageViewA::OnUpdateEditClear(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(::IsClipboardFormatAvailable(CF_DIB)); 
	//当剪贴板为空,ID_EDIT_CLEAR菜单项不可用 
} 
void CImageViewA::OnEditCopy()  
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	// Clean clipboard of contents, and copy the DIB. 
 
	if (OpenClipboard()) 
	{ 
		BeginWaitCursor(); 
		EmptyClipboard(); 
		SetClipboardData (CF_DIB, ::CopyHandle((HANDLE) pDoc->GetHDIB()) ); 
		CloseClipboard(); 
		EndWaitCursor(); 
	} 
	 
} 
 
void CImageViewA::OnUpdateEditCopy(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(GetDocument()->GetHDIB() != NULL); 
    //当内存DIB为空,ID_EDIT_COPY菜单项不可用 
	 
} 
 
void CImageViewA::OnEditCut()  
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	// Clean clipboard of contents, and copy the DIB. 
	BeginWaitCursor(); 
	if (pDoc->GetHDIB() != NULL) 
	{ 
	  
		if (OpenClipboard()) 
			{ 
			EmptyClipboard(); 
			SetClipboardData (CF_DIB, ::CopyHandle((HANDLE) pDoc->GetHDIB()) ); 
			CloseClipboard(); 
			} 
		pDoc->ReplaceHDIB((HDIB)NULL); // and free the old DIB 
		pDoc->InitDIBData();    // set up new size & palette 
		pDoc->SetModifiedFlag(TRUE); 
 
		SetScrollSizes(MM_TEXT, pDoc->GetDocSize()); 
//		OnDoRealize((WPARAM)m_hWnd,0);  // realize the new palette 
		pDoc->UpdateAllViews(NULL); 
	} 
	EndWaitCursor(); 
	 
} 
 
void CImageViewA::OnUpdateEditCut(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(GetDocument()->GetHDIB() != NULL); 
	//当内存DIB为空,ID_EDIT_CUT菜单项不可用 
	 
} 
 
void CImageViewA::OnEditPaste()  
{ 
	// TODO: Add your command handler code here 
	HDIB hNewDIB = NULL; 
 
	if (OpenClipboard()) 
	{ 
		BeginWaitCursor(); 
 
		hNewDIB = (HDIB) CopyHandle(::GetClipboardData(CF_DIB)); 
 
		CloseClipboard(); 
 
		if (hNewDIB != NULL) 
		{ 
			CImageDocA* pDoc = GetDocument(); 
			pDoc->ReplaceHDIB(hNewDIB); // and free the old DIB 
			pDoc->InitDIBData();    // set up new size & palette 
			pDoc->SetModifiedFlag(TRUE); 
 
			SetScrollSizes(MM_TEXT, pDoc->GetDocSize()); 
//			OnDoRealize((WPARAM)m_hWnd,0);  // realize the new palette 
			pDoc->UpdateAllViews(NULL); 
		} 
		EndWaitCursor(); 
	} 
	 
} 
 
void CImageViewA::OnUpdateEditPaste(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(::IsClipboardFormatAvailable(CF_DIB)); 
	//当剪贴板为空,ID_EDIT_PASTE菜单项不可用 
	 
} 
void CImageViewA::OnEditRedo()  
{ 
	HDIB hNewDIB = NULL; 
 
	if (m_HandleForRedo!=NULL) 
	{ 
		BeginWaitCursor(); 
 
		hNewDIB = (HDIB) CopyHandle(m_HandleForRedo); 
 
		if (hNewDIB != NULL) 
		{ 
			CImageDocA* pDoc = GetDocument(); 
			ReplaceHandleForUndo(pDoc->GetHDIB()); 
			pDoc->ReplaceHDIB(hNewDIB); // and free the old DIB 
			pDoc->InitDIBData();    // set up new size & palette 
			pDoc->SetModifiedFlag(TRUE); 
 
			SetScrollSizes(MM_TEXT, pDoc->GetDocSize()); 
			pDoc->UpdateAllViews(NULL); 
		} 
		ReplaceHandleForRedo(NULL); 
		EndWaitCursor(); 
	} 
	 
} 
 
void CImageViewA::OnUpdateEditRedo(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(m_HandleForRedo != NULL); 
    //当Redo备份句柄为空,ID_EDIT_REDO菜单项不可用 
} 
 
void CImageViewA::OnEditUndo()  
{ 
	// TODO: Add your command handler code here 
	HDIB hNewDIB = NULL; 
 
	if (m_HandleForUndo!=NULL) 
	{ 
		BeginWaitCursor(); 
 
		hNewDIB = (HDIB) CopyHandle(m_HandleForUndo); 
		 
		if (hNewDIB != NULL) 
		{ 
			CImageDocA* pDoc = GetDocument(); 
			ReplaceHandleForRedo(pDoc->GetHDIB()); 
			pDoc->ReplaceHDIB(hNewDIB); // and free the old DIB 
			pDoc->InitDIBData();    // set up new size & palette 
			pDoc->SetModifiedFlag(TRUE); 
 
			SetScrollSizes(MM_TEXT, pDoc->GetDocSize()); 
			pDoc->UpdateAllViews(NULL); 
		} 
		ReplaceHandleForUndo(NULL); 
		EndWaitCursor(); 
	} 
	 
} 
 
void CImageViewA::OnUpdateEditUndo(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(m_HandleForUndo != NULL); 
    //当Undo备份句柄为空,ID_EDIT_UNDO菜单项不可用 
	 
} 
 
 
void CImageViewA::ReplaceHandleForUndo(HGLOBAL h) 
{ 
	if (m_HandleForUndo != NULL) 
	{ 
		::GlobalFree(m_HandleForUndo); 
	} 
	m_HandleForUndo=::CopyHandle(h); 
} 
 
void CImageViewA::ReplaceHandleForRedo(HGLOBAL h) 
{ 
	if (m_HandleForRedo != NULL) 
	{ 
		::GlobalFree(m_HandleForRedo); 
	} 
	m_HandleForRedo=::CopyHandle(h); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA 打印 
/*MFC的默认打印流程 
ID_FILE_PRINT						 \ 
   -> CImageDocA::OnFilePrint()            \ 
ID_FILE_PRINT_PREVIEW                  | ==>   
   -> CView::OnFilePrintPreview()     / 
         CView::DoPrintPreview       / 
										 
			CMyView::OnPreparePrinting(CPrintInfo* pInfo ) 
				CView::DoPreparePrinting( CPrintInfo* pInfo ) 
					对话框 CPrintDialog.DoModal(); 
					创建打印设备描述表 
					打印进程对话框AFX_IDD_PRINTDLG 
			CMyView::OnBeginPrinting( CDC* pDC, CPrintInfo* pInfo ) 
			CDC::StartDoc( LPDOCINFO lpDocInfo ) 
	 			┌─> CMyView::OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL ) 
	 			│    CDC::StartPage() 
	 			│    CMyView::OnPrint( CDC* pDC, CPrintInfo* pInfo ) 
	 			│              CMyView::OnDraw(CDC* pDC) 
	 			│					{ 
     			│						if(pDC->IsPrinting())  {.......} 
     			│					} 
	 			└─  CDC::EndPage() 
			CDC::EndDoc() 
CMyView::OnEndPrinting( CDC* pDC, CPrintInfo* pInfo ) 
*/	 
 
BOOL CImageViewA::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CImageViewA::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
{ 
	// TODO: add extra initialization before printing 
	CScrollView::OnBeginPrinting(pDC,pInfo); 
} 
 
void CImageViewA::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) 
{ 
	// TODO: add cleanup after printing 
	CScrollView::OnEndPrinting(pDC,pInfo); 
} 
 
void CImageViewA::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{ 
	// TODO: add code to print the controls 
	CScrollView::OnPrint(pDC,  pInfo);//call OnDraw(pDC) 
} 
 
void CImageViewA::UpdateDocument(HDIB hNewDIB) 
{ 
	if (hNewDIB != NULL) 
	{ 
		CImageDocA* pDoc = GetDocument(); 
		CSize sizeOld= pDoc->GetDocSize(); 
		pDoc->ReplaceHDIB(hNewDIB); // and free the old DIB 
//		pDoc->InitDIBData();    // set up new size & palette 
//		pDoc->SetModifiedFlag(TRUE); 
//		SetScrollSizes(MM_TEXT, pDoc->GetDocSize()); 
//		OnDoRealize((WPARAM)m_hWnd,0);  // realize the new palette 
//		pDoc->UpdateAllViews(NULL); 
		CSize size=pDoc->GetDocSize(); 
		SetScrollSizes(MM_TEXT, size); 
 
 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImageViewA 鼠标处理 
 
 
 
 
/*1998.12.27 灰度图象使用,设置 
	m_entryImage.hDIB			//源位图句柄 
	m_entryImage.pImage			//源位图数据开始位(用于灰度图) 
	m_entryImage.rectImage		//包围选中区域的最小矩形 
	m_entryImage.sizeImage		//图象大小 
 
*/ 
BOOL CImageViewA::BeginUseGray() 
{ 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->GetHDIB()==NULL) return FALSE; 
 
	m_entryImage.hDIB=NULL;					//源位图句柄 
	m_entryImage.hNewDIB=NULL;				//生成目标位图句柄 
	m_entryImage.pImage=NULL;				//源位图数据开始位(用于灰度图) 
	m_entryImage.pNewImage=NULL;			//目标位图数据开始位(用于灰度图) 
	m_entryImage.hBitmap=NULL;				//源临时中间设备相关位图句柄 
	m_entryImage.hNewBitmap=NULL;			//目标临时中间设备相关位图句柄 
	m_entryImage.hMemDC=NULL;				//源位图设备 
	m_entryImage.hNewDC=NULL;				//目标位图设备 
	m_entryImage.rectImage=CRect(0,0,1,1);		//包围选中区域的最小矩形 
	m_entryImage.sizeImage=CSize(1,1);		//图象大小 
 
	m_entryImage.sizeImage.cx=pDoc->GetDocSize().cx; 
	m_entryImage.sizeImage.cy=pDoc->GetDocSize().cy; 
 
 
	LPBITMAPINFOHEADER  lpBi; 
	m_entryImage.hDIB=pDoc->GetHDIB(); 
	lpBi=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)	m_entryImage.hDIB);//取得原有位图 
	m_entryImage.pImage=(BYTE FAR*)::FindDIBBits((LPSTR)lpBi); 
 
	return TRUE; 
} 
 
/*1998.12.27 彩色图象使用,设置 
	m_entryImage.hDIB			//源位图句柄 
	m_entryImage.hBitmap		//源临时中间设备相关位图句柄 
	m_entryImage.hMemDC			//源位图设备 
	m_entryImage.rectImage		//包围选中区域的最小矩形 
	m_entryImage.sizeImage		//图象大小 
*/ 
BOOL CImageViewA::BeginUseColor() 
{ 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->GetHDIB()==NULL) return FALSE; 
 
	m_entryImage.hDIB=NULL;					//源位图句柄 
	m_entryImage.hNewDIB=NULL;				//生成目标位图句柄 
	m_entryImage.pImage=NULL;				//源位图数据开始位(用于灰度图) 
	m_entryImage.pNewImage=NULL;			//目标位图数据开始位(用于灰度图) 
	m_entryImage.hBitmap=NULL;				//源临时中间设备相关位图句柄 
	m_entryImage.hNewBitmap=NULL;			//目标临时中间设备相关位图句柄 
	m_entryImage.hMemDC=NULL;				//源位图设备 
	m_entryImage.hNewDC=NULL;				//目标位图设备 
	m_entryImage.rectImage=CRect(0,0,1,1);		//包围选中区域的最小矩形 
	m_entryImage.sizeImage=CSize(1,1);		//图象大小 
 
	m_entryImage.sizeImage.cx=pDoc->GetDocSize().cx; 
	m_entryImage.sizeImage.cy=pDoc->GetDocSize().cy; 
 
	HDC hDC=::GetDC(NULL); 
	m_entryImage.hMemDC=::CreateCompatibleDC(hDC); 
	 
	m_entryImage.hBitmap=::DIBToBitmap(pDoc->GetHDIB(),  
		NULL); 
	if(!m_entryImage.hBitmap ) return FALSE; 
	if(!::SelectObject(m_entryImage.hMemDC,m_entryImage.hBitmap))	return FALSE; 
 
//	::SelectClipRgn(m_entryImage.hNewDC,m_Region); 
	::DeleteDC(hDC); 
 
	return TRUE; 
} 
 
/*1998.12.27 灰度图象使用结束,设置 
	m_entryImage.hDIB			//源位图句柄 
	m_entryImage.pImage			//源位图数据开始位(用于灰度图) 
 
*/ 
BOOL CImageViewA::EndUseGray() 
{ 
	::GlobalUnlock((HGLOBAL)m_entryImage.hDIB); 
	return TRUE; 
} 
 
/*1998.12.27 彩色图象使用结束,设置 
	m_entryImage.hBitmap		//源临时中间设备相关位图句柄 
	m_entryImage.hMemDC			//源位图设备 
*/ 
BOOL CImageViewA::EndUseColor() 
{ 
	::DeleteDC(m_entryImage.hMemDC); 
	::DeleteObject(m_entryImage.hBitmap); 
	return TRUE; 
} 
 
/* 
1999-03-13,鲍捷,图像处理算法范例:底片效果 
在IPX工程应用版(A版)中没有提供进度条,也没有区域和标注的功能 
 
*/ 
 
 
void CImageViewA::OnColorNegative()  
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	 
 
	if(pDoc->IsGray()) 
	{ 
		//灰度图像 
		BeginProcessingGray(); 
	    DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
		for(DWORD i=0;iEnable(pDoc->GetHDIB() != NULL ); 	 
} 
 
 
 
//////////////////////////////////////////////////// 
//1999,6,5   王毅 算法:膨胀 
 
 
void CImageViewA::OnMenuitemPENGZHANG() //膨胀 
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->IsGray()) 
    { 
		BeginProcessingGray(); 
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
 
 
	//定义动态数组或创建图象,有待改进 
        BYTE *fsecond; 
		fsecond=new BYTE[w*h]; 
 
	//进行膨胀运算 
        for (DWORD i=2;iIsGray()) 
    { 
		BeginProcessingGray(); 
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
 
 
	//定义动态数组或创建图象,有待改进 
        BYTE  *gfirst;	 
        gfirst=new BYTE[w*h]; 
			 
		//进行腐蚀运算 
		for (DWORD i=2;iGetGrayOldPixel(i-m,j-n)) 
						{min=GetGrayOldPixel(i-m,j-n);} 
					} 
				  gfirst[i*h+j+1]=min; 
                  SetGrayPixel(i,j,gfirst[i*h+j+1]); 
			} 
        EndProcessingGray(); 
	} 
} 
 
void CImageViewA::OnMenuitemSUB() //重建图像。两幅图像相减? 
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->IsGray()) 
    { 
		BeginProcessingGray(); 
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
 
		//图像相减		 
		for(DWORD i = 1 ; i < w-1 ; i++) 
			for(DWORD j = 1 ; j < h-1 ; j++) 
			{ 
				int temp ; 
				temp = GetGrayOldPixel(i,j) - m_pInitImage[i*h+j];				 
				if( temp <0 ) temp = -temp; 
				//temp += 30; 
				if( temp >255 ) temp = 255; 
				temp = 255 - temp; 
				//m_pRecoImage[i*h+j] = temp; 
				SetGrayPixel(i,j,temp); 
			} 
 
 
		EndProcessingGray(); 
 
        BackUpRecoImage();//调用备份函数 
	} 
} 
 
 
 
void CImageViewA::OnMenuitemTHILEV() //三层化。求另一幅图像的直方图? 
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->IsGray()) 
    { 
		BeginProcessingGray(); 
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
 
 
		//统计直方图,及概率 
		int iHtg[256];//图像的直方图 
		for (int c=0;c<256;c++) 
		{ 
			iHtg[c]=0; 
		} 
 
 
        for (DWORD i=1;i (M[0]+M[1]+M[2])) 
					{ 
						optimal=M[0]+M[1]+M[2]; 
						t1=T[1];m_t1=t1; 
						t2=T[2];m_t2=t2; 
						uOpt[0] = u[0]; 
						uOpt[1] = u[1]; 
						uOpt[2] = u[2]; 
					}										 
				   
			}//for ( T[2]  )结束 
		}//for ( T[1]  )结束 
 
		//此处得到最佳的阈值t1,t2 
 		PrintVar("门限1: %d  , 门限2: %d" , m_t1 , m_t2); 
       //还需要 
			        //4. 将图象分成三层 
		//三层化原则: 
//	    unsigned char *gthird=new unsigned char [w*h]; 
 	    for ( i=1;it1)&&(GetGrayOldPixel(i,j)<=t2)) 
				  { 
//					gthird[i*h+j]=(int)((t2-t1)/2+t1); 
     				SetGrayPixel(i,j,BYTE(int(uOpt[1]))); 
				  } 
		       	  else 
				  {                        
//					 gthird[i*h+j]=(int)((255-t2)/2+t2); 
					 SetGrayPixel(i,j,BYTE(int(uOpt[2]))); 
				  } 
			  } 
		  } 
 
        EndProcessingGray(); 
	   } 
 
 
} 
 
//DEL void CImageViewA::OnMenuitemALL() //全过程 
//DEL { 
//DEL 	// TODO: Add your command handler code here 
//DEL     CImageDocA* pDoc = GetDocument(); 
//DEL 	ASSERT_VALID(pDoc); 
//DEL  
//DEL 	if(pDoc->IsGray()) 
//DEL     { 
//DEL 		BeginProcessingGray(); 
//DEL 		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
//DEL  
//DEL  
//DEL 	    //定义动态数组 
//DEL         BYTE *gpengz, *gfirst,*gsecond,*gthird,*gaveragesecond; 
//DEL 		gpengz=new BYTE[w*h]; 
//DEL         gfirst=new BYTE[w*h]; 
//DEL 		gsecond=new BYTE[w*h]; 
//DEL 		gthird=new BYTE[w*h]; 
//DEL 		gaveragesecond=new BYTE[w*h]; 
//DEL  
//DEL 	    //进行膨胀运算 
//DEL         for (DWORD i=2;i gpengz[(i+m)*h+(j+n)] ) 
//DEL 						{ min = gpengz[(i+m)*h+(j+n)]; } 
//DEL 					} 
//DEL 				gfirst[i*h+j]=min; 
//DEL 			////重建图像,两幅图像相减 
//DEL 				insert = GetGrayOldPixel(i,j) - gfirst[i*h+j]; 
//DEL  
//DEL 				if(insert < 0)   	{ insert = - insert;} 
//DEL  
//DEL 				if(insert > 255)   	{ insert = 255;} 
//DEL  
//DEL 				insert = 255 - insert ;			     
//DEL 				gsecond[i*h+j]=insert;				 
//DEL 				 
//DEL 			} 
//DEL         //求平均值   
//DEL 		for ( i=2;i(M[0]+M[1]+M[2])) 
//DEL 					{ 
//DEL 						optimal=M[0]+M[1]+M[2]; 
//DEL 						t1=T[1]; 
//DEL 						t2=T[2];							 
//DEL 					}										 
//DEL 				   
//DEL 			} 
//DEL 			        //4. 将图象分成三层 
//DEL  	for ( i=2;i=0)&&(gsecond[i*h+j]<=t1)) 
//DEL 			{ 
//DEL 				gthird[i*h+j]=(int)(t1-0)/2; 
//DEL                  
//DEL 			} 
//DEL 			else 
//DEL 			{ 
//DEL 				if( (gsecond[i*h+j]>t1)&&(gsecond[i*h+j]<=t2)) 
//DEL 				{ 
//DEL 					gthird[i*h+j]=(int)((t2-t1)/2+t1); 
//DEL 					 
//DEL 				} 
//DEL 		       	else 
//DEL 				{                        
//DEL 					 gthird[i*h+j]=(int)((255-t2)/2+t2); 
//DEL 					  
//DEL 				} 
//DEL 			} 
//DEL 		} 
//DEL 	//图象二值化 
//DEL  
//DEL  
//DEL    	for ( i=1;iGetDocSize(); 
 
	if(!GetDocument()->IsGray()) return; 
	if(m_pInitImage) 
	{ 
		delete m_pInitImage; 
	} 
	m_pInitImage = new BYTE[size.cx * size.cy]; 
 
	BeginUseGray(); 
	for(int i = 0 ; i < size.cx ; i ++) 
		for(int j = 0 ; j < size.cy ; j ++) 
		{ 
			m_pInitImage[i * size.cy +j] = GetGrayOldPixel(i,j); 
		} 
	EndUseGray(); 
} 
 
//1999-06-10,备份重建图像的全局变量 
void CImageViewA::BackUpRecoImage() 
{ 
    CSize size=GetDocument()->GetDocSize(); 
 
	if(!GetDocument()->IsGray()) return; 
	if(m_pRecoImage) 
	{ 
		delete m_pRecoImage; 
	} 
    m_pRecoImage = new BYTE[size.cx * size.cy]; 
 
	BeginUseGray(); 
	for(int i = 0 ; i < size.cx ; i ++) 
		for(int j = 0 ; j < size.cy ; j ++) 
		{ 
			m_pRecoImage[i * size.cy +j] = GetGrayOldPixel(i,j); 
		} 
	EndUseGray(); 
} 
 
void CImageViewA::OnMenuitembilevel() //直接二值化 
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->IsGray()) 
    { 
		BeginProcessingGray(); 
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
 
		PrintVar("门限1: %d  , 门限2: %d" , m_t1 , m_t2); 
				//统计直方图,及概率 
		int iHtg[256]; 
		double fProbb[256]; 
        for (DWORD i=1;i(M[0]+M[1]+M[2])) 
					{ 
						optimal=M[0]+M[1]+M[2]; 
						t1=T[1]; 
						t2=T[2];							 
					}										 
				   
			} 
 
		BYTE *gaveragesecond = new BYTE [w*h]; 
		//图象二值化 
        for ( i=2;i=0 && GetGrayOldPixel(i,j)<=t1 ) 
			{ 
				 
                SetGrayPixel(i,j,0); 
			} 
			else 
			{ 
				if( GetGrayOldPixel(i,j)>t1 && GetGrayOldPixel(i,j)<=t2 && GetGrayOldPixel(i,j)<= gaveragesecond[i*h+j] ) 
				{					 
					SetGrayPixel(i,j,0); 
				} 
		       	else 
				{                    
					 SetGrayPixel(i,j,255); 
				} 
			} 
		} 
		EndProcessingGray(); 
	} 
} 
 
void CImageViewA::OnMenuitemtwol() //二值化 
{ 
	// TODO: Add your command handler code here 
	CImageDocA* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	if(pDoc->IsGray()) 
    { 
		BeginProcessingGray(); 
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
 
		PrintVar("第一段均值 :  %f\n第二段均值 :  %f\n第三段均值 :  %f\n", 
			     uOpt[0] , uOpt[1] , uOpt[2]); 
 
		//图象二值化 
		BYTE *gaveragesecond = new BYTE [w*h]; 
        for (DWORD i=1;i IsGray() ) 
	{ 
		//if( pDoc -> GetHDIB() ) 
 		//	m_stkUnRedo.PushUndo(CopyHandle((HGLOBAL)pDoc->GetHDIB())); 
  
		BeginProcessingGray();  
		DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; 
		for(DWORD i=0;iIsGray())		BeginUseGray(); 
	else             	    BeginUseColor();  
 
    DWORD w=m_entryImage.sizeImage.cx, h=m_entryImage.sizeImage.cy; 
	 
	if(pDoc->IsGray()) 
		Hist.GrayInitialize(m_entryImage.pImage,w,h); 
	else 
		Hist.Initialize(m_entryImage.hMemDC,w,h); 
 
	if(pDoc->IsGray())		EndUseGray(); 
	else				    EndUseColor();  
	 
	//直方图平滑 
//	Hist.GraySmooth(NULL,NULL,NULL,3, sqrt(2*log(2)) ); 
//	CHistogramDlg dlg1;	dlg1.Initialize(&Hist);	dlg1.DoModal(); 
 
	//在此分析直方图 
	/*entriopy_based methed 1 
	 (G.Johannsen,etc.Proc.6th.Icpr,1982)*/ 
 	int i, j, k, k0, gmax; 
		 
 	double cta, m, max, d, n1, n2; 
		 
	//直方图归一化////////////////////////////// 
	double hist[256], sum = 0; 
	for(i = 0 ; i < 256 ; i++) 
	{ 
		sum += Hist.GetValue(i); 
	} 
	for(i = 0 ; i < 256 ; i++) 
	{ 
		hist[i] = Hist.GetValue(i) / sum; 
	} 
 	///////////////////////////////////////////// 
	i = 0; 
	while ( hist[i] == 0 )  i++ ;//找出非零端点Tmin  (k) 
	k = i; 
	gmax = 255; 
	while( hist[gmax] == 0 )  gmax -- ;//找出非零端点Tmax  (gmax) 
	d = 0; 
	while ( k != gmax ) 
	{ 
		k0 = k; max = ( -PI/2 ); 
		for( i = k0 + 1 ; i <= gmax; i++ ) 
		{ 
			m = ( hist[i] - hist[k0] ) / ( i - k0 ); 
			cta = atan( m ); 
			if( cta >= max ) 
				{ max = cta;  k = i; }// max 为最大斜率 ,k为此处的灰度值 
		} 
		n1 = hist[k] / (k-k0);   
		n2 = hist[k0] / (k-k0); 
		for( i = k0 + 1; i < k - 1;  i++ ) 
		{ 
           m = (i - k0) * n1 + ( k - i ) * n2 - hist[i]; 
		   if( m > d )   { d = m; j = i; } 
		} 
	} 
   threshold = j; 
   return threshold; 
}