399 lines
9.5 KiB
C++
399 lines
9.5 KiB
C++
// 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<uchar>(y);
|
||
uchar* dst = reinterpret_cast<uchar*>(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);
|
||
|
||
}
|
||
|