15.3.6 远程摄像头--创建客户方工程(2)
(4)参考图15.13,将openCV目录下GDI+库中的PictureConvert.h PictureConvert.cpp加入到工程中,并在VideoClientDlg.h文件中添加如下代码:
- 01 #include "CameraDS.h"
- 02 #include "Msg_Public.h"
- 03 #include "PictureConvert.h"
- 04 #pragma comment(lib, "strmiids.lib")
- 05 #pragma comment(lib, "cxcore.lib")
- 06 #pragma comment(lib, "cv.lib")
- 07 #pragma comment(lib, "ml.lib")
- 08 #pragma comment(lib, "cvaux.lib")
- 09 #pragma comment(lib, "highgui.lib")
- 10 #pragma comment(lib, "cvcam.lib")
- 11 #pragma comment(lib, "cvcam.lib")
- 12 //以上代码显示连接openCV库
- 13 #include "TcpClient.h"
- 14 typedef struct VideoDataDibStruct
- 15 {//IplImage转为BMP的结构
- 16 DWORD height; //图像高
- 17 DWORD width; //图像宽
- 18 DWORD lineBytes; //1行图像字节数
- 19 DWORD lineBytes24; //24位色1行图像字节数
- 20 DWORD totalSize; //BMP图像总大小字节数
- 21 BYTE pData[1024*225]; //指向BMP图像数据缓冲区
- 22 }VIDEODATADIB;
【代码解析】
第2行包含服务方和客户方公有消息定义头文件。第3行包含转换BMP数据到JPG数据实现头文件。第14~22行定义摄像头数据转为BMP数据的结构。
(5)为CVideoClientDlg类添加成员变量,代码如下:
- CTcpClient m_videoClient; //客户方连接对象
- CCameraDS m_CameraDS; //摄像头设备对象
- CPictureConvert m_PictureConvert; //BMP与JPG互转类对象
(6)为CVideoClientDlg类添加类成员函数IplImage2Bmp(),实现IplImage结构转为BMP图片数据。代码如下: - bool IplImage2Bmp(IplImage *img, VIDEODATADIB *bmpData);
在IplImage2Bmp()函数中添加如下代码:- 01 Bool CVideoClientDlg::IplImage2Bmp(IplImage *img, VIDEODATADIB
- *bmpData);
- 02 {
- 03 DWORD height = img->height; //图片高
- 04 DWORD width = img->width; //图片宽
- 05 DWORD lineBytes = (width*8+31)/32*4;
- //计算8位色图1行字节数(4字节对齐)
- 06 DWORD lineBytes24 = (width*24+31)/32*4;
- //计算24位色图1行字节数(4字节对齐)
- 07 bmpData->heightheight = height;
- 08 bmpData->widthwidth = width;
- 09 bmpData->lineByteslineBytes = lineBytes;
- 10 bmpData->lineBytes24lineBytes24 = lineBytes24;
- 11 bmpData->totalSize = height*lineBytes24;
- //图像总字节数等于图像高×24位色每行字节数
- 12 WORD bitCount;
- 13 if(img->nChannels == 1) //以下只处理8位和24位色图片
- 14 {
- 15 bitCount = 8; //8位色图
- 16 }
- 17 else if(img->nChannels == 3)
- 18 {
- 19 bitCount = 24; //24位色图
- 20 }
- 21 else
- 22 {//其他格式的图片不进行转换
- 23 return false;
- 24 }
- 25 if(bitCount==8)
- 26 { //如果是8位色图,则转为8位色对应的BMP图数据,8位色图每像素8位也就是占 1字节大小
- 27 for(int i=0; i<img->height; i++)
- 28 {
- 29 for(int j=0,n=0; j<img->width*3; j++,n++)
- 30 { *((bmpData->pData)+lineBytes24*(height-1-i)+j)
- =(BYTE)
- 31 ((uchar*)(img->imageData+img->widthStep*i))[n];
- 32 j++; //转换第i行j列的第1个字节
- 33 *((bmpData->pData)+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)
- (img->ImageData+img->widthStep*i))[n];
- 34 j++ ; //转换第i行j列的第2个字节
- 35*((bmpData->pData)+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->I
- mageData+img->widthStep*i))[n]; //转换第i行j列的第3个字节
- 36 }
- 37 }
- 38 }
- 39 else
- 40 { //如果是24位色图,则转为24位色对应BMP图数据
- //24位色图每像素占24位也就是3个字节
- 41 for(int i=0; i<img->height; i++)
- 42 {
- 43 for(int j=0,n=0; j<img->width*3; j++,n++)
- 44 {
- 45*((bmpData->pData)+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->i
- mageData+img->widthStep*i))[3*n]; //转换第i行j列的像素第1个字节
- 46 j++;
- 47*((bmpData->pData)+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->I
- mageData+img->widthStep*i))[3*n+1]; //转换第i行j列的像素第2个字节
- 48 j++;
- 49*((bmpData->pData)+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->i
- mageData+img->widthStep*i))[3*n+2] //转换第i行j列的像素第3个字节
- 50 }
- 51 }
- 52 }
- 53 return true;
- 54 }