|
|
@@ -1,21 +1,39 @@
|
|
|
#include "CAIxuexiPageUI.h"
|
|
|
|
|
|
+#include "../wnd/CMainWnd.h"
|
|
|
+#include "../worker/CVideoCaptureWorker.h"
|
|
|
+
|
|
|
#define WM_TIMER_VIDEO_UPDATE 200002
|
|
|
|
|
|
CAIxuexiPageUI::CAIxuexiPageUI()
|
|
|
{
|
|
|
-
|
|
|
+ m_hBitmap = NULL;
|
|
|
+ m_hMemDC = NULL;
|
|
|
}
|
|
|
|
|
|
CAIxuexiPageUI::~CAIxuexiPageUI()
|
|
|
{
|
|
|
- ::KillTimer(NULL, WM_TIMER_VIDEO_UPDATE);
|
|
|
+ if (m_hBitmap)
|
|
|
+ {
|
|
|
+ DeleteObject(m_hBitmap);
|
|
|
+ m_hBitmap = NULL;
|
|
|
+ }
|
|
|
+ if (m_hMemDC)
|
|
|
+ {
|
|
|
+ DeleteDC(m_hMemDC);
|
|
|
+ m_hMemDC = NULL;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
void CAIxuexiPageUI::InitShow()
|
|
|
{
|
|
|
- ::SetTimer(NULL, WM_TIMER_VIDEO_UPDATE, 1500, NULL);
|
|
|
+ if (m_isFirstInit)
|
|
|
+ {
|
|
|
+ m_isFirstInit = false;
|
|
|
+
|
|
|
+ std::thread(&CAIxuexiPageUI::HandleUpdateVideo, this).detach();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//处理按钮点击类事件
|
|
|
@@ -50,5 +68,92 @@ void CAIxuexiPageUI::HandleTextCapture(std::string content)
|
|
|
|
|
|
bool CAIxuexiPageUI::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
{
|
|
|
+ if (uMsg == WM_AI_XUEXI_UPDATE)
|
|
|
+ {
|
|
|
+ UpdateVideoShow();
|
|
|
+ }
|
|
|
+
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+void CAIxuexiPageUI::HandleUpdateVideo()
|
|
|
+{
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ if (m_pMainWnd->GetCurPageName() != CMainWnd::AIXUEXI)
|
|
|
+ {
|
|
|
+ Sleep(30);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ cv::Mat img;
|
|
|
+ CVideoCaptureWorker::GetInstance()->GetFrame(img);
|
|
|
+
|
|
|
+ if (img.empty())
|
|
|
+ {
|
|
|
+ Sleep(30);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (img.type() != CV_8UC3)
|
|
|
+ {
|
|
|
+ // 仅支持 3 通道彩色图像
|
|
|
+ cvtColor(img, img, cv::COLOR_GRAY2BGR);
|
|
|
+ }
|
|
|
+
|
|
|
+ //缩放尺寸,适合在界面上展示,过大过小都不好看,这个尺寸是根据界面上image控件的大小来定的,可以根据实际情况调整
|
|
|
+ cv::resize(img, img, cv::Size(480, 360), 0, 0, cv::INTER_LINEAR);
|
|
|
+
|
|
|
+ // 创建或更新位图
|
|
|
+ HDC hDC = GetDC(NULL);
|
|
|
+ if (m_hBitmap)
|
|
|
+ {
|
|
|
+ DeleteObject(m_hBitmap);
|
|
|
+ }
|
|
|
+
|
|
|
+ BITMAPINFO bmi = { 0 };
|
|
|
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
+ bmi.bmiHeader.biWidth = img.cols;
|
|
|
+ bmi.bmiHeader.biHeight = -img.rows; // 翻转 Y 轴(OpenCV 与 GDI 坐标方向相反)
|
|
|
+ bmi.bmiHeader.biPlanes = 1;
|
|
|
+ bmi.bmiHeader.biBitCount = 24;
|
|
|
+ bmi.bmiHeader.biCompression = BI_RGB;
|
|
|
+
|
|
|
+ m_hBitmap = CreateDIBitmap(hDC, &bmi.bmiHeader, CBM_INIT, img.data, &bmi, DIB_RGB_COLORS);
|
|
|
+ ReleaseDC(NULL, hDC);
|
|
|
+
|
|
|
+ ::PostMessage(m_pMainWnd->GetHWND(), WM_AI_XUEXI_UPDATE, 0, 0);
|
|
|
+
|
|
|
+ // 控制帧率,避免过度占用 CPU,30 FPS 大约是每 33 毫秒更新一次
|
|
|
+ Sleep(1000 / 30);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CAIxuexiPageUI::UpdateVideoShow()
|
|
|
+{
|
|
|
+ HDC hDC = m_pManager->GetPaintDC();
|
|
|
+
|
|
|
+ if (!m_hMemDC)
|
|
|
+ {
|
|
|
+ m_hMemDC = CreateCompatibleDC(hDC);
|
|
|
+ }
|
|
|
+
|
|
|
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
|
|
|
+ BITMAP bm;
|
|
|
+ GetObject(m_hBitmap, sizeof(BITMAP), &bm);
|
|
|
+
|
|
|
+ CControlUI* pImage = static_cast<CControlUI*>(this->FindSubControl(_T("image")));
|
|
|
+ if (!pImage)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ RECT imageRect = pImage->GetPos();
|
|
|
+
|
|
|
+ StretchBlt(hDC, imageRect.left, imageRect.top, imageRect.right - imageRect.left,
|
|
|
+ imageRect.bottom - imageRect.top, m_hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
|
|
|
+
|
|
|
+ SelectObject(m_hMemDC, hOldBitmap);
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|