// CameraViewReview.cpp : 구현 파일입니다. // #include "stdafx.h" #include "CameraView_Review.h" #include "CHImageControls/CHImageData.h" #include "CHImageControls/CHBufferDC.h" #include using namespace CHImageControls; // CCameraView_Review IMPLEMENT_DYNAMIC(CCameraView_Review, CCameraView) CCameraView_Review::CCameraView_Review(int nViewIndex, CWnd* pParentWnd) : CCameraView(nViewIndex, pParentWnd) { m_bDrawRoiRect = TRUE; m_rtRoiRect = CRect(0,0,0,0); m_bDrawDefectPos = FALSE; m_ptDefectPos = CPoint(-1, -1); m_bDrawReviewAlignRect = FALSE; m_rtReviewAlignRect = CRect(0,0,0,0); m_bDrawAoiDefect = FALSE; m_rtAoiDefectRect = CRect(0,0, 128, 128); m_AoiDefectImage.CreateImage(128, 128, 8, 1); m_AoiDefectImage.ClearImage(0); m_rectTracker.m_rect = CRect(0,0,0,0); m_rectTracker.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeOutside | crossLine | xLine; m_rectTracker.m_sizeMin = CSize(8,8); m_bDrawTracker = FALSE; } CCameraView_Review::~CCameraView_Review() { m_AoiDefectImage.ReleaseImage(); } BEGIN_MESSAGE_MAP(CCameraView_Review, CCameraView) ON_COMMAND(IDR_DEFECT_POS,&CCameraView_Review::OnDefectPos) ON_COMMAND(IDR_ROI_RECT,&CCameraView_Review::OnROIRect) ON_COMMAND(IDR_CLEAR_ROI_RECT,&CCameraView_Review::OnClearROIRect) ON_COMMAND(IDR_SAVE_ROI_RECT,&CCameraView_Review::OnSaveROIRect) ON_COMMAND(IDR_SAVE_AS_IMAGE, &CCameraView_Review::OnSaveAsImage) ON_COMMAND(IDR_CHANGE_VIEW, &CCameraView_Review::OnChangeView) ON_COMMAND(IDR_AOI_DEFECT, &CCameraView_Review::OnAoiDefect) ON_COMMAND(IDR_LOAD_AOI_IMAGE, &CCameraView_Review::OnLoadAoiImage) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_RBUTTONDBLCLK() ON_WM_SETCURSOR() ON_WM_MOUSEMOVE() END_MESSAGE_MAP() // CCameraView_Review 메시지 처리기입니다. void CCameraView_Review::SetDrawRoiRect(BOOL bDraw) { m_bDrawRoiRect = bDraw; Invalidate(TRUE); } void CCameraView_Review::SetDrawReviewAlignRect( BOOL bDraw ) { m_bDrawReviewAlignRect = bDraw; Invalidate(TRUE); } void CCameraView_Review::SetDrawDefectPos(BOOL bDraw) { m_bDrawDefectPos = bDraw; Invalidate(TRUE); } void CCameraView_Review::SetDrawAoiDefect(BOOL bDraw) { m_bDrawAoiDefect = bDraw; Invalidate(TRUE); } void CCameraView_Review::DrawROIRect(CDC *pDC) { if (m_rtRoiRect.Width()==0 || m_rtRoiRect.Height()==0) return; CPen pen, *pOldPen; pen.CreatePen(PS_DOT, 1, RGB(0,0,255)); pOldPen = pDC->SelectObject(&pen); pDC->SelectStockObject(NULL_BRUSH); pDC->Rectangle(m_rtRoiRect.left,m_rtRoiRect.top,m_rtRoiRect.right,m_rtRoiRect.bottom); CFont font; VERIFY(font.CreateFont( 15, // nHeight 6, // nWidth 0, // nEscapement 0, // nOrientation FW_NORMAL, // nWeight FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut ANSI_CHARSET, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily _T("Arial"))); // lpszFacename // Do something with the font just created... CFont* def_font = pDC->SelectObject(&font); // pDC->SetTextColor(RGB(255,255,255)); // pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(255,255,0)); pDC->SetBkColor(RGB(0, 0, 0)); pDC->SetBkMode(OPAQUE); CString strValue = _T(""); strValue.Format(_T("[Region] %d, %d, %d, %d"), m_rtRoiRect.left, m_rtRoiRect.top, m_rtRoiRect.right, m_rtRoiRect.bottom); pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+5, strValue); strValue.Format(_T("[Width] %d pix, %.3lf um"), m_sROIInfo.nWidthPixel, m_sROIInfo.dWidthRealUM); pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+25, strValue); strValue.Format(_T("[Height] %d pix, %.3lf um"), m_sROIInfo.nHeightPixel, m_sROIInfo.dHeightRealUM); pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+45, strValue); strValue.Format(_T("[Diagonal] %.3lf pix, %.3lf um"), m_sROIInfo.dDiagonalPixel, m_sROIInfo.dDiagonalRealUM); pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+65, strValue); strValue.Format(_T("[Resol_X] %.6lf um/pixel"), (m_dResolution/m_dWidthScale)); pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+85, strValue); strValue.Format(_T("[Resol_Y] %.6lf um/pixel"), (m_dResolution/m_dHeightScale)); pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+105, strValue); pDC->SelectObject(def_font); } void CCameraView_Review::DrawReviewAlignRect( CDC *pDC ) { if (m_rtReviewAlignRect.Width()==0 || m_rtReviewAlignRect.Height()==0) return; CPen pen, *pOldPen; pen.CreatePen(PS_DOT, 1, RGB(255,0,0)); pOldPen = pDC->SelectObject(&pen); pDC->SelectStockObject(NULL_BRUSH); pDC->Rectangle(m_rtReviewAlignRect.left,m_rtReviewAlignRect.top,m_rtReviewAlignRect.right,m_rtReviewAlignRect.bottom); // CFont font; // VERIFY(font.CreateFont( // 15, // nHeight // 6, // nWidth // 0, // nEscapement // 0, // nOrientation // FW_NORMAL, // nWeight // FALSE, // bItalic // FALSE, // bUnderline // 0, // cStrikeOut // ANSI_CHARSET, // nCharSet // OUT_DEFAULT_PRECIS, // nOutPrecision // CLIP_DEFAULT_PRECIS, // nClipPrecision // DEFAULT_QUALITY, // nQuality // DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily // _T("Arial"))); // lpszFacename // // // Do something with the font just created... // CFont* def_font = pDC->SelectObject(&font); // pDC->SetTextColor(RGB(255,255,0)); // pDC->SetBkColor(RGB(0, 0, 0)); // pDC->SetBkMode(OPAQUE); // // CString strValue = _T(""); // strValue.Format(_T("[Region] %d, %d, %d, %d"), m_rtRoiRect.left, m_rtRoiRect.top, m_rtRoiRect.right, m_rtRoiRect.bottom); // pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+5, strValue); // // strValue.Format(_T("[Width] %d pix, %.3lf um"), m_sROIInfo.nWidthPixel, m_sROIInfo.dWidthRealUM); // pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+25, strValue); // // strValue.Format(_T("[Height] %d pix, %.3lf um"), m_sROIInfo.nHeightPixel, m_sROIInfo.dHeightRealUM); // pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+45, strValue); // // strValue.Format(_T("[Diagonal] %.3lf pix, %.3lf um"), m_sROIInfo.dDiagonalPixel, m_sROIInfo.dDiagonalRealUM); // pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+65, strValue); // // strValue.Format(_T("[Resol_X] %.6lf um/pixel"), (m_dResolution/m_dWidthScale)); // pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+85, strValue); // // strValue.Format(_T("[Resol_Y] %.6lf um/pixel"), (m_dResolution/m_dHeightScale)); // pDC->TextOut(m_rtRoiRect.right+5, m_rtRoiRect.top+105, strValue); // // pDC->SelectObject(def_font); } void CCameraView_Review::OnDefectPos() { m_bDrawDefectPos = !m_bDrawDefectPos; Invalidate(TRUE); } void CCameraView_Review::OnROIRect() { m_bDrawRoiRect = !m_bDrawRoiRect; Invalidate(TRUE); } void CCameraView_Review::OnAoiDefect() { m_bDrawAoiDefect = !m_bDrawAoiDefect; Invalidate(TRUE); } void CCameraView_Review::OnClearROIRect() { ClearTrackerRect(); m_rtRoiRect = CRect(0,0,0,0); Invalidate(TRUE); } BOOL CCameraView_Review::GetTrackerRect(CRect& rtRect) { if (m_rectTracker.m_rect.Width()<0 || m_rectTracker.m_rect.Height()<0) { return FALSE; } rtRect = m_rectTracker.m_rect; return TRUE; } void CCameraView_Review::DrawDefectPos(CDC *pDC) { if (m_ptDefectPos.x==-1 || m_ptDefectPos.y==-1) return; pDC->SelectStockObject(WHITE_PEN); pDC->SelectStockObject(NULL_BRUSH); CRect rtRect; rtRect.left = m_ptDefectPos.x - 50; rtRect.right = m_ptDefectPos.x + 50; rtRect.top = m_ptDefectPos.y - 50; rtRect.bottom = m_ptDefectPos.y + 50; pDC->Rectangle(rtRect); } void CCameraView_Review::DrawAoiDefect(CDC *pDC) { if (!m_AoiDefectImage.GetImageExist()) return; CRect rect; GetClientRect(rect); int nLeft = rect.Width() - m_rtAoiDefectRect.Width() - 10; int nTop = rect.Height() - m_rtAoiDefectRect.Height() - 10; int nRight = nLeft + m_rtAoiDefectRect.Width(); int nBottom = nTop + m_rtAoiDefectRect.Height(); m_AoiDefectImage.ShowImage(pDC->m_hDC, CRect(nLeft, nTop, nRight, nBottom)); pDC->SelectStockObject(BLACK_PEN); pDC->SelectStockObject(NULL_BRUSH); pDC->Rectangle(nLeft, nTop, nLeft+m_rtAoiDefectRect.Width(), nTop+m_rtAoiDefectRect.Height()); } void CCameraView_Review::SetDefectPos(const CPoint& ptPoint) { m_ptDefectPos = ptPoint; Invalidate(TRUE); } void CCameraView_Review::SetTrackerRect(const CRect& rtRect) { m_rectTracker.m_rect = rtRect; Invalidate(TRUE); } void CCameraView_Review::ClearTrackerRect() { m_rectTracker.m_rect = CRect(0,0,0,0); Invalidate(TRUE); } void CCameraView_Review::OnSaveROIRect() { if (m_rtRoiRect.Width()<1 || m_rtRoiRect.Height()<1) return; CString szFilter = _T("All Files(*.*)|*.*||"); CString strPath; CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY, szFilter); dlg.m_ofn.lpstrTitle = _T("Save Image"); if(dlg.DoModal() == IDCANCEL) return; CRect rtRect; rtRect.left = int(double(m_rtRoiRect.left) / m_dWidthScale + 0.5); rtRect.top = int(double(m_rtRoiRect.top) / m_dHeightScale + 0.5); rtRect.right = int(double(m_rtRoiRect.right) / m_dWidthScale + 0.5); rtRect.bottom = int(double(m_rtRoiRect.bottom) / m_dHeightScale + 0.5); CCHImageData subImage; if (GetSubImage(rtRect, &subImage)==FALSE) { return; } if (subImage.SaveImage(dlg.GetPathName())==FALSE) return; return; } void CCameraView_Review::OnLoadAoiImage() { CString szFilter = _T("All Files(*.*)|*.*||"); CString strPath; CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter); dlg.m_ofn.lpstrTitle = _T("Load AOI Image"); if(dlg.DoModal() == IDOK) { EnterCriticalSection(&m_csImageData); if (m_AoiDefectImage.LoadImage(dlg.GetPathName())) { Invalidate(TRUE); } LeaveCriticalSection(&m_csImageData); } } BOOL CCameraView_Review::LoadAoiImage(const CString& strFilename) { EnterCriticalSection(&m_csImageData); if (m_AoiDefectImage.LoadImage(strFilename)) { Invalidate(TRUE); return TRUE; } LeaveCriticalSection(&m_csImageData); return FALSE; } BOOL CCameraView_Review::GetAoiImage(CCHImageData* pImageData) { if (!m_AoiDefectImage.GetImageExist()) return FALSE; EnterCriticalSection(&m_csImageData); BOOL bReturn = m_AoiDefectImage.CopyImageTo(pImageData); LeaveCriticalSection(&m_csImageData); return bReturn; } BOOL CCameraView_Review::SetAoiImage(CCHImageData* pImageData) { if (pImageData==NULL) return FALSE; if (!pImageData->GetImageExist()) return FALSE; EnterCriticalSection(&m_csImageData); m_AoiDefectImage.CopyImageFrom(pImageData); LeaveCriticalSection(&m_csImageData); Invalidate(FALSE); return TRUE; } BOOL CCameraView_Review::SetAoiImage(int nWidth, int nHeight, int nChannels, int nWidthStep, const BYTE* pBuffer) { if (nWidth<0 || nHeight<0 || nChannels<0 || pBuffer==NULL) return FALSE; EnterCriticalSection(&m_csImageData); if (nWidth!=m_AoiDefectImage.GetWidth() || nHeight!=m_AoiDefectImage.GetHeight() || nChannels!=m_AoiDefectImage.GetChannels()) { if (m_AoiDefectImage.CreateImage(nWidth, nHeight, 8, nChannels)==FALSE) { LeaveCriticalSection(&m_csImageData); return FALSE; } } memcpy(m_AoiDefectImage.GetImageBuffer(), pBuffer, nWidthStep*nHeight); if (nChannels==1) m_nViewBand = BandTypeGray; BOOL bResult = m_AoiDefectImage.GetBandImage(m_nViewBand, this); LeaveCriticalSection(&m_csImageData); return bResult; } void CCameraView_Review::PopUpCommandMenu(const CPoint& point) { CMenu menu; CMenu popMenu; menu.CreateMenu(); // 최상위 뼈대 메뉴 popMenu.CreatePopupMenu(); // 팝업메뉴 BOOL bAddMenu = FALSE; popMenu.AppendMenu(MF_STRING, IDR_LOAD_IMAGE, _T("Load Image")); popMenu.AppendMenu(MF_STRING, IDR_LOAD_AOI_IMAGE, _T("Load AOI Image")); popMenu.AppendMenu(MF_STRING, IDR_SAVE_IMAGE, _T("Save Image")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_STRING, IDR_SAVE_AS_IMAGE, _T("Save as Image")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_SEPARATOR); popMenu.AppendMenu(MF_STRING, IDR_VIEW_NAME, _T("View Name")); popMenu.AppendMenu(MF_STRING, IDR_CENTER_LINE, _T("Center Line")); popMenu.AppendMenu(MF_STRING, IDR_CENTER_RECT, _T("Center Rect")); popMenu.AppendMenu(MF_STRING, IDR_RULER, _T("Ruler")); popMenu.AppendMenu(MF_STRING, IDR_ROI_RECT, _T("ROI Rect")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_STRING, IDR_CLEAR_ROI_RECT, _T("Clear ROI Rect")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_STRING, IDR_SAVE_ROI_RECT, _T("Save ROI Rect")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_STRING, IDR_AOI_DEFECT, _T("AOI Defect")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_SEPARATOR); popMenu.AppendMenu(MF_STRING, IDR_VIEW_ORIGIN, _T("1:1 View")); popMenu.AppendMenu(MF_STRING, IDR_VIEW_FIT, _T("Fit View")); // 색상의 서브메뉴 추가 popMenu.AppendMenu(MF_SEPARATOR); popMenu.AppendMenu(MF_STRING, IDR_VIEW_COLOR, _T("Color")); popMenu.AppendMenu(MF_STRING, IDR_VIEW_GRAY, _T("Gray")); popMenu.AppendMenu(MF_STRING, IDR_VIEW_RED, _T("Red")); popMenu.AppendMenu(MF_STRING, IDR_VIEW_GREEN, _T("Green")); popMenu.AppendMenu(MF_STRING, IDR_VIEW_BLUE, _T("Blue")); popMenu.AppendMenu(MF_SEPARATOR); popMenu.AppendMenu(MF_STRING, IDR_CHANGE_VIEW, _T("Change VIew")); // 메뉴 상태 처리 if (m_bDrawViewName) { popMenu.CheckMenuItem(IDR_VIEW_NAME, MF_CHECKED); } if (m_bDrawCenterLine) { popMenu.CheckMenuItem(IDR_CENTER_LINE, MF_CHECKED); } if (m_bDrawCenterRect) { popMenu.CheckMenuItem(IDR_CENTER_RECT, MF_CHECKED); } if (m_bDrawRuler) { popMenu.CheckMenuItem(IDR_RULER, MF_CHECKED); } if (m_bDrawRoiRect) { popMenu.CheckMenuItem(IDR_ROI_RECT, MF_CHECKED); } if (m_bDrawAoiDefect) { popMenu.CheckMenuItem(IDR_AOI_DEFECT, MF_CHECKED); } switch(m_nViewMode) { case 0: popMenu.CheckMenuItem(IDR_VIEW_ORIGIN, MF_CHECKED); break; case 1: popMenu.CheckMenuItem(IDR_VIEW_FIT, MF_CHECKED); break; } // 메뉴 상태 처리 switch(m_nViewBand) { case BandTypeRed: popMenu.CheckMenuItem(IDR_VIEW_RED, MF_CHECKED); break; case BandTypeGreen: popMenu.CheckMenuItem(IDR_VIEW_GREEN, MF_CHECKED); break; case BandTypeBlue: popMenu.CheckMenuItem(IDR_VIEW_BLUE, MF_CHECKED); break; case BandTypeGray: popMenu.CheckMenuItem(IDR_VIEW_GRAY, MF_CHECKED); break; default: popMenu.CheckMenuItem(IDR_VIEW_COLOR, MF_CHECKED); break; } // 컨텍스트 메뉴 호출 CRect rect; GetWindowRect(rect); int nX = rect.left + point.x; int nY = rect.top + point.y; popMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, nX, nY, this); } BOOL CCameraView_Review::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (m_rectTracker.SetCursor(this, nHitTest)) { return TRUE; } return CCameraView::OnSetCursor(pWnd, nHitTest, message); } void CCameraView_Review::OnSaveAsImage() { CCameraView::OnSaveImage(); } void CCameraView_Review::OnChangeView() { if (m_pParentWnd==NULL) return; m_pParentWnd->SendMessage(IDR_CHANGE_VIEW); } void CCameraView_Review::OnPaint() { CCHBufferDC *pDC = new CCHBufferDC(this); // device context for painting UpdateView(pDC); if (m_bDrawAoiDefect) DrawAoiDefect(pDC); if (m_bDrawRoiRect) DrawROIRect(pDC); if(m_bDrawReviewAlignRect)DrawReviewAlignRect(pDC); if (m_bDrawDefectPos) DrawDefectPos(pDC); m_rectTracker.m_rect.NormalizeRect(); if (m_rectTracker.m_rect.left>0 && m_rectTracker.m_rect.right0 && m_rectTracker.m_rect.bottom -1 && point.x < GetScaleWidth() && point.y > -1 && point.y < GetScaleHeight() ) { if (m_rectTracker.HitTest(point) < 0) { // just to demonstrate CRectTracker::TrackRubberBand if (m_rectTracker.TrackRubberBand(this, point, TRUE)) { Invalidate(); } } else if (m_rectTracker.Track(this, point, TRUE)) { Invalidate(); } } } CCameraView::OnLButtonDown(nFlags, point); } void CCameraView_Review::OnLButtonUp(UINT nFlags, CPoint point) { if (GetTrackerRect(m_rtRoiRect)) { m_sROIInfo.nWidthPixel = m_rtRoiRect.Width(); m_sROIInfo.nHeightPixel = m_rtRoiRect.Height(); m_sROIInfo.dDiagonalPixel = sqrt(double(m_sROIInfo.nWidthPixel*m_sROIInfo.nWidthPixel + m_sROIInfo.nHeightPixel*m_sROIInfo.nHeightPixel)); m_sROIInfo.dWidthRealUM = m_sROIInfo.nWidthPixel * (m_dResolution / m_dWidthScale) ; m_sROIInfo.dHeightRealUM = m_sROIInfo.nHeightPixel * (m_dResolution / m_dHeightScale); m_sROIInfo.dDiagonalRealUM = sqrt((m_sROIInfo.dWidthRealUM*m_sROIInfo.dWidthRealUM)+(m_sROIInfo.dHeightRealUM*m_sROIInfo.dHeightRealUM)); Invalidate(TRUE); } CCameraView::OnLButtonUp(nFlags, point); } void CCameraView_Review::SetReviewAlginRect(BOOL bShow ,const CRect& rtRect ) { m_rtReviewAlignRect.left = (int)ceil(rtRect.left * m_dWidthScale); m_rtReviewAlignRect.right = (int)ceil(rtRect.right * m_dWidthScale); m_rtReviewAlignRect.top = (int)ceil(rtRect.top * m_dHeightScale); m_rtReviewAlignRect.bottom = (int)ceil(rtRect.bottom * m_dHeightScale); SetDrawReviewAlignRect(bShow); Invalidate(TRUE); } BOOL CCameraView_Review::GetReviewAlginRect( CRect& rtRect ) { rtRect = m_rtReviewAlignRect; return TRUE; }