基于MFC实现大华监控摄像头Demo(视频流和抓图)

根据大华官方的SDK包以及Demo文件(官网可以下载到)实现一些最基本的功能:登陆,注销,实时监视,抓图。先上一下博主自己做的结果图:视频流
抓图

本人的环境配置如下:

  • 操作系统:Win7 64位
  • 开发工具:Visual Studio 2017 ;X86
  • 摄像头型号:大华DH-IPC-HFW2233DM-LED

实现流程如下:

  • 步骤1 调用SDK包中的相关库文件,完成 SDK 初始化流程,部分代码如下:
#pragma comment(lib , "dhnetsdk.lib")
#pragma comment(lib, "dhconfigsdk.lib")// 也可以在项目路径下添加lib文件,在项目属性中包含目录添加相关路径

// 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK 会调用该函数(必须有)
void __stdcall DisConnectFunc(LONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser){	}

//自动重连回调函数
void __stdcall HaveReConnectFunc(LONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser){    }

//子连接自动重连回调函数
void __stdcall SubHaveReConnectFunc(EM_INTERFACE_TYPE emInterfaceType, BOOL bOnline, LLONG lOperateHandle, LLONG lLoginID, LDWORD dwUser){   }
//SDK初始化
void CRealPlayDlg::InitNetSDK()
{
	CLIENT_Init(DisConnectFunc, (LDWORD)this);
//我选择直接在这里设置抓图回调函数
	CLIENT_SetSnapRevCallBack(SnapPicRet,(LDWORD)this);
  • 步骤2 初始化成功后,调用库函数 CLIENT_LoginWithHighLevelSecurity 登录设备。
int g_nPort = 0; // tcp 连接端口,需与期望登录设备页面 tcp 端口配置一致
char g_szUserName[32] = { 0 };//设备用户名
char g_szPasswd[32] = { 0 };//密码
char g_szDevIp[32] = {0};//设备IP
int nChannelID = 0;//预览通道号


void CRealPlayDlg::OnBnClickedLogin()
{
    char *pchUserName = (LPSTR)(LPCSTR)g_szUserName;
	char *pchPassword = (LPSTR)(LPCSTR)g_szPasswd;
	m_nPort = GetDlgItemInt(IDC_EDIT3);
	
	GetDlgItemText(IDC_IPADDRESS1, g_szDevIp, 32);
	GetDlgItemText(IDC_EDIT1, pchUserName, 32);
	GetDlgItemText(IDC_EDIT2, pchPassword, 32);
	
NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;//登录接口函数输入参数
memset(&stInparam, 0, sizeof(stInparam));// 初始化结构体对象
stInparam.dwSize = sizeof(stInparam);// 结构体大小
// 将设备信息拷贝到登录接口函数输入参数
strncpy(stInparam.szIP, g_szDevIp, sizeof(stInparam.szIP) - 1);
strncpy(stInparam.szPassword, pchPassword, sizeof(stInparam.szPassword) - 1);
strncpy(stInparam.szUserName, pchUserName, sizeof(stInparam.szUserName) - 1);
stInparam.nPort = m_nPort;
stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;// TCP登陆, 默认方式

NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;//登录接口函数输出参数
memset(&stOutparam, 0, sizeof(stOutparam));// 清空结构体对象
stOutparam.dwSize = sizeof(stOutparam);

//登陆设备
LLONG lRet = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);
  • 步骤3 登录成功后,调用库函数 CLIENT_RealPlayEx 启动实时监视,参数 hWnd 为有效窗口句柄。并调用 CLIENT_SetSnapRevCallBack 设置抓图回调函数,当 SDK 收到设备端发送过来的抓图数据时,会调用 fSnapRev回调函数回调图片信息及图片数据给用户。
void CRealPlayDlg::OnBnClickedPlay()
{
 	    // 传入有效窗口句柄
		HWND play1 = GetDlgItem(IDC_STATIC)->m_hWnd;

		//开启实时监视
		//int nChannelID = 0; // 预览通道号
		DH_RealPlayType emRealPlayType = DH_RType_Realplay; // 实时监视
		g_lRealHandle = CLIENT_RealPlayEx(g_lLoginHandle, nChannelID, play1,
			emRealPlayType);
	}
	
	//抓图回调函数
void CALLBACK SnapPicRet(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{
	CRealPlayDlg *pThis = (CRealPlayDlg*)dwUser;
	pThis->OnOnePicture(ILoginID, pBuf, RevLen, EncodeType, CmdSerial);
}

  • 步骤4 调用 CLIENT_SnapPictureEx 发送抓图命令给前端设备,在 fSnapRev 回调函数中等待设备回复的图片信息。
// 发送抓图命令
void CRealPlayDlg::OnBnClickedcp()
{
	// TODO: 在此添加控件通知处理程序代码
		// 发送抓图命令给前端设备
	UpdateData(TRUE);
	SNAP_PARAMS snapParams;
	snapParams.Channel = 0;//默认通道 ID 为 0、抓图模式为抓一幅图,用户可根据实际情况自行选择
	snapParams.mode = 0;// 抓图模式;-1:表示停止抓图, 0:表示请求一帧, 1:表示定时发送请求, 2:表示连续请求
	snapParams.CmdSerial = 0;// 请求序列号,有效值范围 0~65535,超过范围会被截断为 unsigned short
	CLIENT_SnapPicture(g_lLoginHandle, snapParams);
}

//抓图保存代码块
void CRealPlayDlg::OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial)
{
	//文件保存路径
	char path[1000];
	int filelen = GetModuleFileName(NULL, path, 1000);//获取程序所在目录,返回32位无符号整数
	int i = filelen;
	while (path[i] != '\\')
	{
		i--;
	}
	path[i + 1] = '\0';

	//文件命名
	CString filepath(path);
	CString filename = "mpeg4.JPG";
	CString strfile = filepath + filename;
	char *pFileName = strfile.GetBuffer(200);

	/* 保存原始图片文件*/
	FILE *stream;
	if ((stream = fopen((const char*)pFileName, "wb")) != NULL)
	{
		int numwritten = fwrite(pBuf, sizeof(char), RevLen, stream);
		fclose(stream);
	}

	/*判断图像编码类型。如果是一个I帧的mpeg4,然后调用I帧解码为BMP显示.*/
	if (EncodeType == 0)
	{
		//int iRet = IFrameToBmp("tmp.bmp",pFileName);
		//if (iRet == 1)
		//{
		//	ShowBitmap("tmp.bmp");
		//}
	}
	else if (EncodeType == 10)
	{ 
		//ShowBitmap(pFileName);
		ShowSnapImage(pFileName);
		
	}
}

//抓图展示相关代码
void CRealPlayDlg::ShowSnapImage(LPCSTR szImagePath)
{
	USES_CONVERSION;
	// 获取展示窗口
	CWnd* fullImageWindow = GetDlgItem(IDC_SHOWPICTURE);
	if (NULL == fullImageWindow)
	{
		return;
	}
	RECT rect;
	fullImageWindow->GetWindowRect(&rect);
	CDC* pDC = NULL;
	pDC = fullImageWindow->GetWindowDC();
	if (NULL == pDC)
	{
		return;
	}
	// 加载图片
	HRESULT hr = S_FALSE;
	hr = OleLoadPicturePath(T2OLE(szImagePath), NULL, 0, RESERVED_COLOR, IID_IPicture, (LPVOID*)&m_pPicture);
	if (NULL == m_pPicture)
	{
		fullImageWindow->ReleaseDC(pDC);
		return;
	}

	//显示全图
	OLE_XSIZE_HIMETRIC hmWidth;
	OLE_YSIZE_HIMETRIC hmHeight;
	m_pPicture->get_Width(&hmWidth);
	m_pPicture->get_Height(&hmHeight);

	hr = m_pPicture->Render(*pDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, hmHeight, hmWidth, -hmHeight, NULL);
	fullImageWindow->ReleaseDC(pDC);
}
  • 步骤5 实时监视使用完毕后,调用库函数 CLIENT_StopRealPlayEx 停止实时监视,并调用 CLIENT_Logout 退出设备。
void CRealPlayDlg::OnBnClickedStop()
{
	// 停止播放
	 CLIENT_StopRealPlayEx(g_lRealHandle);
	Invalidate(); 
}

void CRealPlayDlg::OnBnClickedLogout()
{
	// 登出设备
	if (0 != g_lLoginHandle)
	CLIENT_Logout(g_lLoginHandle);
	
	g_lLoginHandle = 0;
  • 步骤6 SDK 功能使用完后,调用 CLIENT_Cleanup 释放 SDK 资源。
void CRealPlayDlg::OnDestroy()
{
	CDialogEx::OnDestroy();
	// TODO: 在此处添加消息处理程序代码
	CLIENT_Cleanup();
}

以上所展示的代码只是程序中的一个部分,均是基于大华SDK开发手册所写的,相关库函数手册里面都有详细描述,后面我会把车牌识别功能加上去,如果以上有错误还劳烦大佬们指出。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值