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;i Enable(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;i IsGray()) { BeginProcessingGray(); DWORD w=m_entryImage.sizeImage.cx,h=m_entryImage.sizeImage.cy; //定义动态数组或创建图象,有待改进 BYTE *gfirst; gfirst=new BYTE[w*h]; //进行腐蚀运算 for (DWORD i=2;i GetGrayOldPixel(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;i t1)&&(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;i GetDocSize(); 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;i IsGray()) 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; }