fast/Plugin/Fast/FastView.cpp
2025-01-20 10:30:01 +08:00

399 lines
9.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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);
}
//参数1opencv即将读的图
//参数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);
}