// PictureView.cpp : 实现文件 // #include "stdafx.h" #include "resource.h" #include "FastView.h" #include "DahuaFisheyeCamera.h" #include "HikRgdbCamera.h" //图像尺寸类型 enum { IMG_SIZE_NORMAL, //图像宽高均在绘图范围内 IMG_SIZE_WIDTH_BEYOND, //仅图像宽度超出绘图范围 IMG_SIZE_HEIGHT_BEYOND, //仅图像高度超出绘图范围 IMG_SIZE_BOTH_BEYOND //图像宽高均超出绘图范围 }; // CPictureView IMPLEMENT_DYNAMIC(CFastView, CStatic) CFastView::CFastView() { m_pCameraDlg = NULL; } CFastView::~CFastView() { } BEGIN_MESSAGE_MAP(CFastView, CStatic) ON_WM_PAINT() ON_WM_SIZE() ON_WM_CTLCOLOR() ON_WM_RBUTTONUP() END_MESSAGE_MAP() // CPictureView 消息处理程序 void CFastView::StartPlay(CString strFile) { StopPlay(); m_Image.Destroy(); ShowWindow(SW_SHOW); if (0 == strFile.GetLength()) return; m_Image.Load(strFile); //根据图片路径加载图片 DrawPicture(); } void CFastView::StopPlay() { m_Image.Destroy(); UpdateWindow(); ShowWindow(SW_HIDE); } void CFastView::CalculateImageRect() { //如果当前图像为空,则返回 if (m_Image.IsNull()) return; CRect rectWnd; GetWindowRect(&rectWnd); int MemWidth = rectWnd.Width(); int MemHeight = rectWnd.Height(); //m_ImageRect = CRect(0, 0, MemWidth, MemHeight); //全屏缩放 //return; //获取图像矩形区域 CRect rectImg = CRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()); int ImgWidth = rectImg.Width(); int ImgHeight = rectImg.Height(); int nImgSizeType; //图像尺寸类型 //默认不收缩投影区域 int nGap = 0; //获取当前图像尺寸类型 if ((ImgWidth <= MemWidth - nGap) && (ImgHeight <= MemHeight - nGap)) nImgSizeType = IMG_SIZE_NORMAL; else if ((ImgWidth>MemWidth - nGap) && (ImgHeight <= MemHeight - nGap)) nImgSizeType = IMG_SIZE_WIDTH_BEYOND; else if ((ImgWidth <= MemWidth - nGap) && (ImgHeight>MemHeight - nGap)) nImgSizeType = IMG_SIZE_HEIGHT_BEYOND; else nImgSizeType = IMG_SIZE_BOTH_BEYOND; //对不同的图像尺寸,计算投影区域矩形 switch (nImgSizeType) { float fScaleW, fScaleH; //X、Y方向的缩小率 int nW, nH; //只有宽超出显示范围 case IMG_SIZE_WIDTH_BEYOND: fScaleW = ((double)MemWidth) / ImgWidth; nW = MemWidth; nH = fScaleW*ImgHeight; m_ImageRect = CRect((MemWidth - nW) / 2 + nGap, (MemHeight - nH) / 2, (MemWidth + nW) / 2 - nGap, (MemHeight + nH) / 2); break; //只有高超出显示范围 case IMG_SIZE_HEIGHT_BEYOND: fScaleH = ((double)MemHeight) / ImgHeight; nW = fScaleH*ImgWidth; nH = MemHeight; m_ImageRect = CRect((MemWidth - nW) / 2, (MemHeight - nH) / 2 + nGap, (MemWidth + nW) / 2, (MemHeight + nH) / 2 - nGap); break; //宽高都超出显示范围 //长、宽均在显示范围内 case IMG_SIZE_BOTH_BEYOND: case IMG_SIZE_NORMAL: fScaleW = ((double)MemWidth) / ImgWidth; fScaleH = ((double)MemHeight) / ImgHeight; float fScale = min(fScaleW, fScaleH); nW = fScale*ImgWidth; nH = fScale*ImgHeight; m_ImageRect = CRect((MemWidth - nW) / 2 + nGap, (MemHeight - nH) / 2 + nGap, (MemWidth + nW) / 2 - nGap, (MemHeight + nH) / 2 - nGap); break; } } void CFastView::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CStatic::OnPaint() if (FALSE == m_Image.IsNull()) { CDC *pDC = GetDC();//获得pictrue控件的DC //解决CIMage缩放失真问题 SetStretchBltMode(pDC->m_hDC, HALFTONE); SetBrushOrgEx(pDC->m_hDC, 0, 0, NULL); CRect rectWnd = { 0 }; GetWindowRect(&rectWnd); //重绘底色 pDC->FillSolidRect(CRect(0, 0, rectWnd.Width(), rectWnd.Height()), RGB(0, 0, 0)); //m_Image.StretchBlt(pDC->GetSafeHdc(), m_ImageRect, CRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight())); m_Image.Draw(pDC->m_hDC, m_ImageRect); //将图片画到Picture控件表示的矩形区域 ReleaseDC(pDC);//释放picture控件的DC } } void CFastView::OnSize(UINT nType, int cx, int cy) { CStatic::OnSize(nType, cx, cy); DrawPicture(); // TODO: 在此处添加消息处理程序代码 } void CFastView::DrawPicture() { if (FALSE == m_Image.IsNull()) { CalculateImageRect(); if (m_ImageRect.Width() <= 0) return; CDC *pDC = GetDC();//获得pictrue控件的DC CRect rectWnd; GetWindowRect(&rectWnd); //重绘底色 //pDC->FillSolidRect(CRect(0, 0, rectWnd.Width(), rectWnd.Height()), RGB(0, 0, 0)); //解决CIMage缩放失真问题 //SetStretchBltMode(pDC->m_hDC, HALFTONE); //SetBrushOrgEx(pDC->m_hDC, 0, 0, NULL); SetStretchBltMode(pDC->m_hDC, COLORONCOLOR); SetBrushOrgEx(pDC->m_hDC, 0, 0, NULL); //dc.SetStretchBltMode //m_Image.StretchBlt(pDC->GetSafeHdc(), CRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()), m_ImageRect); m_Image.Draw(pDC->GetSafeHdc(), m_ImageRect); //将图片画到Picture控件表示的矩形区域 ReleaseDC(pDC);//释放picture控件的DC } } HBRUSH CFastView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CStatic::OnCtlColor(pDC, pWnd, nCtlColor); CBrush brush; brush.CreateSolidBrush(RGB(0, 0, 0)); // TODO: 在此更改 DC 的任何特性 pDC->SetBkColor(RGB(0, 0, 0)); return (HBRUSH)brush; // TODO: 如果默认的不是所需画笔,则返回另一个画笔 return hbr; } UINT CFastView::CameraThreadFunc(PVOID pv) { //循环遍历摄像头,为每个摄像头创建独立的线程 ST_THREAD_PARAM *pParam = (ST_THREAD_PARAM *)pv; CFastView *pThis = (CFastView*)pParam->pParent; int nIdx = pParam->nIdx; delete pv; if (pThis->m_nCameraTyp == HIK_RGBD) { pThis->m_pCameraDlg = new CHikRgdbCamera(pThis, nIdx); pThis->m_pCameraDlg->Create(IDD_DLG_CAM); pThis->m_pCameraDlg->ShowWindow(SW_HIDE); } else if (pThis->m_nCameraTyp == DAHUA_FISHEYE) { pThis->m_pCameraDlg = new CDahuaFisheyeCamera(pThis, nIdx, pThis->m_nPlayTyp); pThis->m_pCameraDlg->Create(IDD_DLG_CAM); pThis->m_pCameraDlg->ShowWindow(SW_HIDE); } /*else if (pThis->m_nCameraTyp == DAHUA_FISHEYE_LIVE) { pThis->m_pCameraDlg = new CDahuaFisheyeLiveCamera(pThis, nIdx); pThis->m_pCameraDlg->Create(IDD_DLG_CAM); pThis->m_pCameraDlg->ShowWindow(SW_HIDE); }*/ //The message loop MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } pThis->m_pCameraDlg->DestroyWindow(); delete pThis->m_pCameraDlg; TRACE(_T("释放对话框")); return 0; } void CFastView::SetCameraInfo(int nIdx, ENUM_CAMERA_TYPE enCameraType, ENUM_PLAY_TYPE enPlayType, String strIp, int nPort) { m_nCameraIdx = nIdx; m_nCameraTyp = enCameraType; m_nPlayTyp = enPlayType; ST_THREAD_PARAM *pParam = new ST_THREAD_PARAM; pParam->nIdx = nIdx; pParam->pParent = this; AfxBeginThread(CFastView::CameraThreadFunc, (void*)pParam); return; } void CFastView::OnRButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 // TODO: Add your message handler code here and/or call default CMenu menu; menu.CreatePopupMenu(); //以下直接利用相应的自定义消息来标记菜单项 menu.AppendMenu(MF_STRING, ID_MRU_SAMPLE, "采样"); //menu.AppendMenu(MF_STRING, WM TEST2, "Test item 2"); //menu.AppendMenu(MF_STRING, WM TEST3, "Test item 3"); //menu.AppendMenu(MF_STRING, WM TEST4, "Test item 4"); //在右击位置下方20像素的地方显示菜单 POINT tpoint; tpoint.x = point.x; tpoint.y = point.y; ClientToScreen(&tpoint); menu.TrackPopupMenu(TPM_LEFTALIGN, tpoint.x, tpoint.y + 20, this); CStatic::OnRButtonDown(nFlags, point); } BOOL CFastView::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 switch (LOWORD(wParam)) { case ID_MRU_SAMPLE: { /*CString strMsg; strMsg.Format("开始启动摄像头%d采样", m_nCameraIndex); AfxMessageBox(strMsg);*/ if (NULL != m_pCameraDlg) { ::PostMessage(m_pCameraDlg->m_hWnd, WM_CAMERA_SNAP, NULL, NULL); } //((CMainFrame*)GetParentFrame())->BeginSample(m_nCameraIndex); break; } default: break; } return CStatic::OnCommand(wParam, lParam); } //参数1:opencv即将读的图, //参数2:需要展示的Picture Control的ID void CFastView::DrawMat(cv::Mat& imageMat, int nOffset) { /*cv::Mat img; int nWidth = imageMat.cols * rect.Height() *1.0 / imageMat.rows; cv::resize(imageMat, img, cv::Size(nWidth, rect.Height()));// 缩放Mat并备份 // 转一下格式 ,这段可以放外面,*/ /*switch (imgTmp.channels()) { case 1: cv::cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道 break; case 3: cv::cvtColor(imgTmp, imgTmp, CV_BGR2BGRA); // BGR三通道 break; default: break; } int pixelBytes = imgTmp.channels() * (imgTmp.depth() + 1); // 计算一个像素多少个字节 // 制作bitmapinfo(数据头) BITMAPINFO bitInfo; bitInfo.bmiHeader.biBitCount = 8 * pixelBytes; bitInfo.bmiHeader.biWidth = imgTmp.cols; bitInfo.bmiHeader.biHeight = -imgTmp.rows; bitInfo.bmiHeader.biPlanes = 1; bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitInfo.bmiHeader.biCompression = BI_RGB; bitInfo.bmiHeader.biClrImportant = 0; bitInfo.bmiHeader.biClrUsed = 0; bitInfo.bmiHeader.biSizeImage = 0; bitInfo.bmiHeader.biXPelsPerMeter = 0; bitInfo.bmiHeader.biYPelsPerMeter = 0; // Mat.data + bitmap数据头 -> MFC CDC* pDC = GetDC(); ::StretchDIBits( pDC->GetSafeHdc(), (rect.Width()-nWidth)/2, 0, nWidth, rect.Height(), 0, 0, nWidth, rect.Height(), imgTmp.data, &bitInfo, DIB_RGB_COLORS, SRCCOPY ); ReleaseDC(pDC);*/ CImage image; image.Create(imageMat.cols, imageMat.rows, 24); for (int y = 0; y < imageMat.rows; ++y) { const uchar* src = imageMat.ptr(y); uchar* dst = reinterpret_cast(image.GetBits()) + y * image.GetPitch(); for (int x = 0; x < imageMat.cols; ++x) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; src += 3; dst += 3; } } HDC hdc = ::GetDC(m_hWnd); CRect rect; GetClientRect(&rect); // 获取控件大小 image.Draw(hdc, rect); image.Destroy(); ::ReleaseDC(m_hWnd, hdc); }