15.3.7 远程摄像头--创建监控方工程(2)
【代码解析】
第4行注册服务方处理消息。第11行创建服务器。第13行创建服务器成功后启动服务器。
(4)为msg_MSG_VIDEO_DATA_C2S()函数添加如下处理代码,作用是处理MSG_VIDEO_DATA_C2S消息接收客户方传来的摄像头视频数据,并且直接在窗口中画出此视频数,代码如下:
- 01 void CVideoSvrDlg::msg_MSG_VIDEO_DATA_C2S(CNetPackage *pNetPack)
- 02 {
- 03 CVideoSvrDlg *pMainWnd = (CVideoSvrDlg *)AfxGetMainWnd();
- 04 int size = pNetPack->ReadInt32();//读取消息内容,JPG数据大小
- 05 char *pJpgMemData = new char[size];
- 06 pNetPack->ReadStruct(pJpgMemData, size);//读取JPF数据内容
- 07 char *bmpMemData = NULL;
- 08 DWORD bmpMemDataSize = 0;
- 09 //转JPG图片数据为BMP图片数据
- 10 BOOL bOK = pMainWnd->m_PictureConvert.ConvertPictrue(pJpgMemData, size, &bmpMemData, &bmpMemDataSize);
- 11 if(bOK == TRUE)
- 12 {
- 13 CRect rect;
- 14 //取得监控视频窗口大小
- 15 pMainWnd->GetDlgItem(IDC_STATIC_VIDEO)->GetClientRect(rect);
- 16 BITMAPFILEHEADER bfh;
- 17 BITMAPINFOHEADER bih;
- 18 memcpy(&bfh, bmpMemData, 14);
- 19 memcpy(&bih, bmpMemData+14, 40);
- 20 BITMAPINFO bi;
- 21 memset(&bi, 0, sizeof(bi));
- 22 memcpy(&bi.bmiHeader, &bih, 40);
- 23 //取得监控视频窗口DC
- 24 CDC *pDC = pMainWnd->GetDlgItem(IDC_STATIC_VIDEO)->GetDC();
- 25 //在监控视频窗口中画出视频图像
- 26 StretchDIBits(pDC->GetSafeHdc(), rect.left, rect.top, rect.
- Width(), rect.Height(),
- 27 0, 0, bih.biWidth, bih.biHeight, bmpMemData+54, &bi,
- 28 DIB_RGB_COLORS, 32 SRCCOPY);
- 29 //释放监控视频窗口DC
- 30 pMainWnd->GetDlgItem(IDC_STATIC_VIDEO)->ReleaseDC(pDC);
- 31 pMainWnd->m_PictureConvert.PictureMemFree(&bmpMemData);
- 32 }
- 33 }
【代码解析】
第4~6行读取网络消息内容。第10行将读取到的JPG数据转为BMP数据。第17~22行构建BMP文件头。第24~31行取得窗口句柄画出此BMP数据到窗口中。编译运行结果如图15.18所示。
|
| (点击查看大图)图15.18 远程摄像头监控运行结果 |
通过本节示例可以总结出远程监控的架构方式:当带摄像头的客户端与服务器连接成功后,定时器就利用CCameraDS类不断地采集摄像头数据,并将该数据转换为BMP图片,进而转换为JPG图片数据,再通过网络传输发送到服务方。这样该服务方就把接收到的图片数据直接显示到监视窗口中了。