// FastLookUpDlg.cpp : 实现文件 // #include "stdafx.h" #include "FastLookUpDlg.h" #include "afxdialogex.h" #include "GlobalFunc.h" #include "CvvImage.h" #include "ImgShowDlg.h" // CFastLookUpDlg 对话框 IMPLEMENT_DYNAMIC(CFastLookUpDlg, CDialogEx) CFastLookUpDlg::CFastLookUpDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CFastLookUpDlg::IDD, pParent) { m_SrcFrame = nullptr; m_iPage = 0; m_ptrParent = nullptr; } CFastLookUpDlg::~CFastLookUpDlg() { m_ptrParent = nullptr; // 情报队列销毁 if(m_ImgStruDeque.size() > 0) { for (size_t i = 0; i < m_ImgStruDeque.size(); i++) { SAFE_DELETE_ARRAY(m_ImgStruDeque[i].buff); } m_ImgStruDeque.clear(); } if (m_SrcFrame != NULL) { cvReleaseImage(&m_SrcFrame); m_SrcFrame = NULL; } } void CFastLookUpDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CFastLookUpDlg, CDialogEx) ON_BN_CLICKED(IDC_BTN_PRE_PAGE, &CFastLookUpDlg::OnBnClickedBtnPrePage) ON_BN_CLICKED(IDC_BTN_NEXT_PAGE, &CFastLookUpDlg::OnBnClickedBtnNextPage) ON_WM_PAINT() ON_WM_LBUTTONDBLCLK() END_MESSAGE_MAP() // CFastLookUpDlg 消息处理程序 void CFastLookUpDlg::SetParentPt(void *pt) { m_ptrParent = pt; } // 设置图像数据 void CFastLookUpDlg::SetImgData(const ImgStru &img) { if(m_ImgStruDeque.size() >= 18) { std::deque::iterator iter; // 定义迭代器 iter = m_ImgStruDeque.begin(); // 释放指针指向的内存 SAFE_DELETE_ARRAY(iter->buff); iter->buff = NULL; // 弹出 m_ImgStruDeque.pop_front(); } // 入队列 ImgStru local; // 局部变量 CloneImgStru(img, local); // 深度复制 m_ImgStruDeque.push_back(local); // 入队,浅复制 // 从而使local中已入队的结构体成为野指针; local.buff = NULL; return; } // 显示图像数据 int CFastLookUpDlg::ShowImgData() { if (m_ImgStruDeque.empty() == true) { return 0; } int showCount = 0; // 当图像小于9张时,一律在第1面显示 if (m_ImgStruDeque.size() <= 9) { m_iPage = 0; } if (m_iPage == 0) { if (m_ImgStruDeque.size() >= 9) { showCount = 9; } else { showCount = m_ImgStruDeque.size(); } for (int i = 0; i < showCount; i++) { // 显示图像 showOneImg(i, m_ImgStruDeque[i]); } GetDlgItem(IDC_STATIC_ORDER1)->SetWindowText("1"); GetDlgItem(IDC_STATIC_ORDER2)->SetWindowText("2"); GetDlgItem(IDC_STATIC_ORDER3)->SetWindowText("3"); GetDlgItem(IDC_STATIC_ORDER4)->SetWindowText("4"); GetDlgItem(IDC_STATIC_ORDER5)->SetWindowText("5"); GetDlgItem(IDC_STATIC_ORDER6)->SetWindowText("6"); GetDlgItem(IDC_STATIC_ORDER7)->SetWindowText("7"); GetDlgItem(IDC_STATIC_ORDER8)->SetWindowText("8"); GetDlgItem(IDC_STATIC_ORDER9)->SetWindowText("9"); } else if (m_iPage == 1) { if (m_ImgStruDeque.size() > 9) { showCount = m_ImgStruDeque.size() - 9; for (size_t i = 9; i < m_ImgStruDeque.size(); i++) { // 显示图像 showOneImg(i, m_ImgStruDeque[i]); } GetDlgItem(IDC_STATIC_ORDER1)->SetWindowText("10"); GetDlgItem(IDC_STATIC_ORDER2)->SetWindowText("11"); GetDlgItem(IDC_STATIC_ORDER3)->SetWindowText("12"); GetDlgItem(IDC_STATIC_ORDER4)->SetWindowText("13"); GetDlgItem(IDC_STATIC_ORDER5)->SetWindowText("14"); GetDlgItem(IDC_STATIC_ORDER6)->SetWindowText("15"); GetDlgItem(IDC_STATIC_ORDER7)->SetWindowText("16"); GetDlgItem(IDC_STATIC_ORDER8)->SetWindowText("17"); GetDlgItem(IDC_STATIC_ORDER9)->SetWindowText("18"); } } return showCount; } // 显示一幅图像 void CFastLookUpDlg::showOneImg(int IDtag, const ImgStru &imgStru) { if (IDtag < 0 || IDtag > 17) { return; } int nID = 0; switch(IDtag) { case 0: case 9: nID = IDC_STATIC_IMG1; break; case 1: case 10: nID = IDC_STATIC_IMG2; break; case 2: case 11: nID = IDC_STATIC_IMG3; break; case 3: case 12: nID = IDC_STATIC_IMG4; break; case 4: case 13: nID = IDC_STATIC_IMG5; break; case 5: case 14: nID = IDC_STATIC_IMG6; break; case 6: case 15: nID = IDC_STATIC_IMG7; break; case 7: case 16: nID = IDC_STATIC_IMG8; break; case 8: case 17: nID = IDC_STATIC_IMG9; break; default: break; } int imgWidth = imgStru.ImgWidth; int imgHeight = imgStru.ImgHeight; int nBitCount = imgStru.bitcount; // 步长:每行像素所占字节数,必须扩展成4的倍数 int lineByte = (imgWidth * nBitCount / 8 + 3) / 4 * 4; // 位图数据缓冲区的大小,即图像大小 unsigned int imgBufSize = static_cast(imgHeight * lineByte); if (imgWidth > 0 && imgHeight > 0 && imgStru.buff != NULL && (nBitCount == 8 || nBitCount == 24)) { // 将图像数据转换到 m_SrcFrame 再显示 if (m_SrcFrame != NULL) // 如果有图像 { // 情况1:如果图像属性没有变化 直接更换原始图像数据即可,即复制图像数据,不需要再去创建一幅图像 // 情况2:如果图像属性发生了变化,需要先释放图像,再创建图像 // 情况1 if ((m_SrcFrame->width == imgWidth) && (m_SrcFrame->height == imgHeight) && (m_SrcFrame->depth * m_SrcFrame->nChannels == nBitCount) ) { // 内存复制机制 int RealLineByte = (imgWidth * nBitCount / 8); if (RealLineByte == lineByte) { memcpy(m_SrcFrame->imageData, imgStru.buff, imgBufSize); // 图像数据复制 } else { for (int i = 0; i < imgHeight; i++) { memcpy(m_SrcFrame->imageData + i * lineByte, imgStru.buff + i * RealLineByte, RealLineByte); } } } else // 情况2 { // 释放图像 cvReleaseImage(&m_SrcFrame); m_SrcFrame = NULL; // 创建 m_SrcFrame = cvCreateImage(cvSize(imgWidth, imgHeight), 8, nBitCount/8); // 创建图像 if (m_SrcFrame != NULL) // 创建成功 { // 内存复制机制 int RealLineByte = (imgWidth * nBitCount / 8); if (RealLineByte == lineByte) { memcpy(m_SrcFrame->imageData, imgStru.buff, imgBufSize); // 图像数据复制 } else { for (int i = 0; i < imgHeight; i++) { memcpy(m_SrcFrame->imageData + i * lineByte, imgStru.buff + i * RealLineByte, RealLineByte); } } } else { return; } } } else // 如果没有图像 需要先创建图像 { m_SrcFrame = cvCreateImage(cvSize(imgWidth, imgHeight), 8, nBitCount/8); // 创建图像 if (m_SrcFrame != NULL) // 创建成功 { // 内存复制机制 int RealLineByte = (imgWidth * nBitCount / 8); if (RealLineByte == lineByte) { memcpy(m_SrcFrame->imageData, imgStru.buff, imgBufSize); // 图像数据复制 } else { for (int i = 0; i < imgHeight; i++) { memcpy(m_SrcFrame->imageData + i * lineByte, imgStru.buff + i * RealLineByte, RealLineByte); } } } else { return; } } // 显示图像 // 获得 pictrue 控件窗口的句柄 CWnd *pWnd = NULL; pWnd = GetDlgItem(nID); // 后面程序无需再判定 if (pWnd == NULL) { return; } // 获取图像控件HDC CDC *pDC = NULL; // 函数退出时需要释放 ReleaseDC(pDC); pDC = pWnd->GetDC(); // 后面程序无需再判定 if (pDC == NULL) { return; } HDC hdc = NULL; hdc = pDC->GetSafeHdc(); if (hdc == NULL) { return; } // 当前图像尺寸 int imgWidth = m_SrcFrame->width; int imgHeight = m_SrcFrame->height; // 显示图像 IplImage* fitSizeImg = NULL; // 显示图像尺寸 int fitSizeImgWidth = 0; int fitSizeImgHeight = 0; CRect rect; pWnd->GetClientRect(&rect); int PicCtrlWidth = rect.Width(); int PicCtrlHeight = rect.Height(); // 图像尺寸小于窗口尺寸 if ((imgWidth <= PicCtrlWidth) && (imgHeight <= PicCtrlHeight)) { // 拉伸图像 double Ratio = 1.0; double Ratio_Width = static_cast(PicCtrlWidth) / static_cast(imgWidth); double Ratio_Height = static_cast(PicCtrlHeight) / static_cast(imgHeight); Ratio = (Ratio_Width < Ratio_Height) ? Ratio_Width : Ratio_Height; // Ratio 大于 1 // 显示图像尺寸 fitSizeImgWidth = static_cast(imgWidth * Ratio + 0.5); fitSizeImgHeight = static_cast(imgHeight * Ratio + 0.5); } else { // 压缩图像 double Ratio = 1.0; double Ratio_Img = static_cast(imgWidth) / static_cast(imgHeight); double Ratio_ClientRect = static_cast(PicCtrlWidth) / static_cast(PicCtrlHeight); // 计算比例系数 if ( Ratio_Img > Ratio_ClientRect ) { Ratio = static_cast(PicCtrlWidth) / static_cast(imgWidth); // Ratio 小于 1 } else { Ratio = static_cast(PicCtrlHeight) / static_cast(imgHeight); // Ratio 小于 1 } // 显示图像尺寸 fitSizeImgWidth = static_cast(imgWidth * Ratio + 0.5); fitSizeImgHeight = static_cast(imgHeight * Ratio + 0.5); } // 最低尺寸判断,小于一个像素时直接返回 if(min(fitSizeImgWidth, fitSizeImgHeight) <= 1) { // 释放 ReleaseDC(pDC); return; } // 创建fitSizeImg fitSizeImg = cvCreateImage(cvSize(fitSizeImgWidth, fitSizeImgHeight), m_SrcFrame->depth, m_SrcFrame->nChannels); if (fitSizeImg == NULL) { return; } // 改变图像尺寸 cvResize(m_SrcFrame, fitSizeImg); // 为使显示界面不闪烁 增加中间变量 边界充满黑色 IplImage* fillblackImg = NULL; fillblackImg = cvCreateImage(cvSize(PicCtrlWidth, PicCtrlHeight), fitSizeImg->depth, fitSizeImg->nChannels); if (fillblackImg != NULL) { cvZero(fillblackImg); // 清零 } else { // 释放缩放后图像 cvReleaseImage(&fitSizeImg); fitSizeImg = NULL; // 释放pdc ReleaseDC(pDC); return; } // 左上 起始点 CPoint LeftUp; LeftUp.x = static_cast((PicCtrlWidth - fitSizeImgWidth)/2); LeftUp.y = static_cast((PicCtrlHeight - fitSizeImgHeight)/2); cvSetImageROI(fillblackImg, cvRect(static_cast(LeftUp.x), static_cast(LeftUp.y), fitSizeImgWidth, fitSizeImgHeight)); cvAdd(fillblackImg, fitSizeImg, fillblackImg); cvResetImageROI( fillblackImg ); // 绘图 CvvImage img; img.CopyOf(fillblackImg); img.Show(hdc, 0, 0, fillblackImg->width, fillblackImg->height); // 释放fitSizeImg cvReleaseImage(&fitSizeImg); fitSizeImg = NULL; // 释放fillblackImg cvReleaseImage(&fillblackImg); fillblackImg = NULL; // 释放 ReleaseDC(pDC); pDC = NULL; } return; } // 向前翻页 void CFastLookUpDlg::OnBnClickedBtnPrePage() { // TODO: 在此添加控件通知处理程序代码 if (m_iPage == 0) { return; } else { m_iPage = 0; ShowImgData(); } } // 向后翻页 void CFastLookUpDlg::OnBnClickedBtnNextPage() { if (m_iPage == 1) { return; } else { m_iPage = 1; ShowImgData(); } } void CFastLookUpDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CDialogEx::OnPaint() ShowImgData(); } BOOL CFastLookUpDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 在此添加额外的初始化 CRect rect; GetDlgItem(IDC_STATIC_IMG1)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[0] = rect; GetDlgItem(IDC_STATIC_IMG2)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[1] = rect; GetDlgItem(IDC_STATIC_IMG3)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[2] = rect; GetDlgItem(IDC_STATIC_IMG4)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[3] = rect; GetDlgItem(IDC_STATIC_IMG5)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[4] = rect; GetDlgItem(IDC_STATIC_IMG6)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[5] = rect; GetDlgItem(IDC_STATIC_IMG7)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[6] = rect; GetDlgItem(IDC_STATIC_IMG8)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[7] = rect; GetDlgItem(IDC_STATIC_IMG9)->GetWindowRect(&rect); ScreenToClient(&rect); m_picCtrlRect[8] = rect; m_bFastLookUpLeft.SubclassDlgItem(IDC_BTN_PRE_PAGE, this); m_bFastLookUpLeft.SetIcon(IDI_ICON_LEFT); m_bFastLookUpLeft.SetTooltipText("上一页"); m_bFastLookUpRight.SubclassDlgItem(IDC_BTN_NEXT_PAGE, this); m_bFastLookUpRight.SetIcon(IDI_ICON_RIGHT); m_bFastLookUpRight.SetTooltipText("下一页"); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } // 判断一个点是否在矩形框内 bool CFastLookUpDlg::pointRectTest(CPoint pt, CRect rect) { if (pt.x >= rect.left && pt.x <= rect.right && pt.y >= rect.top && pt.y <= rect.bottom) { return true; } else { return false; } } void CFastLookUpDlg::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 int i = 0; if (true == pointRectTest(point, m_picCtrlRect[0])) { i = 1; } else if (true == pointRectTest(point, m_picCtrlRect[1])) { i = 2; } else if (true == pointRectTest(point, m_picCtrlRect[2])) { i = 3; } else if (true == pointRectTest(point, m_picCtrlRect[3])) { i = 4; } else if (true == pointRectTest(point, m_picCtrlRect[4])) { i = 5; } else if (true == pointRectTest(point, m_picCtrlRect[5])) { i = 6; } else if (true == pointRectTest(point, m_picCtrlRect[6])) { i = 7; } else if (true == pointRectTest(point, m_picCtrlRect[7])) { i = 8; } else if (true == pointRectTest(point, m_picCtrlRect[8])) { i = 9; } else { i = 0; } if (i >= 1 && i <= 9 && m_iPage == 1) { i = i + 9; } if (m_ptrParent != nullptr) { CImgShowDlg *pt = nullptr; pt = reinterpret_cast(m_ptrParent); if (pt != nullptr) { pt->ShowSelectedImgInMem(i); } } CDialogEx::OnLButtonDblClk(nFlags, point); } // 清理内存记忆 void CFastLookUpDlg::ClearMemory() { try { // 如果有图像 需要释放该图像 if (m_SrcFrame != NULL) { cvReleaseImage(&m_SrcFrame); m_SrcFrame = NULL; } // 情报队列销毁 if(m_ImgStruDeque.size() > 0) { for (size_t i = 0; i < m_ImgStruDeque.size(); ++i) { SAFE_DELETE_ARRAY(m_ImgStruDeque[i].buff); } m_ImgStruDeque.clear(); } // 使窗口无效 if (this->GetSafeHwnd() != NULL) { Invalidate(); } } catch(cv::Exception &e) { e.msg; return; } catch(...) { return; } } // 是否有记忆图像 bool CFastLookUpDlg::isEmpty() { return m_ImgStruDeque.empty(); }