海康威视车牌识别调试
海康威视SDK车牌号识别调试
使用海康官方SDK调试门禁车牌号识别,MFC开发
一、WEB登录设备
首次使用设备需激活,输入说明书写的默认ip地址,用户名admin,修改密码。
进入设备的配置界面,我这里车牌识别方式改为视频识别。
进入预览界面就可以查看视频是否打开成功。
二、环境配置
新建自己的MFC项目,基于对话框项目,运行。
将SDK中库文件中的所有文件和文件夹统一放到你项目中输出有exe的地方。
新建include放头文件。

项目的目录结构
在HKMFCcard.h中加入
#include "HCNetSDK.h"
三、开发
1.界面设计
两个PictureControl分别显示场景图和车牌小图,两个本文框显示状态信息,中间本文框显示车牌号,两个按钮远程开关道闸暂时未开发
2.流程
设备注册 -->> 打开布防 -->> 检测到车牌 -->> 进入回调函数 -->> 抓拍识别 -->> 保存数据 -->> 界面显示
全局变量:
int iNum = 0;
NET_DVR_SETUPALARM_PARAM struSetupParam = { 0 };
3.设备注册
在HKMFcard.cpp中初始化
NET_DVR_Init(); // init DVR
打开软件进行设备注册,将此过程放在了OnInitDialog()中。
//---------------------------------------
//注册设备
//登录参数,包括设备地址、登录用户、密码等
LONG lUserID = -1;
NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 };
struLoginInfo.bUseAsynLogin = 0; //同步登录方式
strcpy(struLoginInfo.sDeviceAddress, "192.168.11.111"); //设备IP地址
struLoginInfo.wPort = 8000; //设备服务端口
strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名
strcpy(struLoginInfo.sPassword, "11111111"); //设备登录密码
//设备信息, 输出参数
NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 };
lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
if (lUserID < 0)
{
/*printf("Login failed, error code: %d\n", NET_DVR_GetLastError());*/
m_textLogin.SetWindowTextA("登录失败");
NET_DVR_Cleanup();
return 0;
}
m_textLogin.SetWindowTextA("登录成功");
4.报警布防
//---------------------------------------
//报警布防
//设置报警回调函数
/*注:多台设备对接时也只需要调用一次设置一个回调函数,不支持不同设备的事件在不同的回调函数里面返回*/
NET_DVR_SetDVRMessageCallBack_V50(0, cbMessageCallback, NULL);
//启用布防
struSetupParam.dwSize = sizeof(NET_DVR_SETUPALARM_PARAM);
struSetupParam.byLevel = 1; //布防优先级:0- 一等级(高),1- 二等级(中)
struSetupParam.byAlarmInfoType = 1; //上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
LONG lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, &struSetupParam);
if (lHandle < 0)
{
//printf("NET_DVR_SetupAlarmChan_V41 failed, error code: %d\n", NET_DVR_GetLastError());
m_textBufang.SetWindowTextA("布防失败");
NET_DVR_Logout(lUserID);
NET_DVR_Cleanup();
return 0;
}
m_textBufang.SetWindowTextA("布防成功");
cbMessageCallback 回调函数,当检测到有车牌号时调用此函数。
5.回调函数
void CALLBACK cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
HWND hWnd = FindWindow(NULL, _T("车牌号识别系统"));
//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。
switch (lCommand)
{
case COMM_UPLOAD_PLATE_RESULT:
{
NET_DVR_PLATE_RESULT struPlateResult = { 0 };
memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
if (hWnd != NULL)
{
SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)((void *)struPlateResult), 0);
}
break;
}
case COMM_ITS_PLATE_RESULT:
{
NET_ITS_PLATE_RESULT struITSPlateResult = { 0 };
memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));
if (/*AfxGetMainWnd()->m_hWnd*/hWnd != NULL)
{
SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)(&struITSPlateResult), 0);
}
break;
}
default:
break;
}
return;
}
使用SendMessage传出消息。
1)宏定义
自定义消息
#define WM_SAVE_DATA (WM_USER + 100) //自定义消息
2)创建映射
BEGIN_MESSAGE_MAP(CHKMFCcardDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_SAVE_DATA, &CHKMFCcardDlg::OnSaveData)
ON_BN_CLICKED(IDC_BUTTON1, &CHKMFCcardDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
3)数据处理OnSaveData及显示
//数据的存储与显示
LRESULT CHKMFCcardDlg::OnSaveData(WPARAM wParam, LPARAM lParam)
{
// 在这里处理数据保存操作
// 例如,将 lParam 解释为指向数据的指针
char filename[100];
FILE *fSnapPic = NULL;
FILE *fSnapPicPlate = NULL;
//NET_ITS_PLATE_RESULT* struITSPlateResult = reinterpret_cast<NET_ITS_PLATE_RESULT*>(lParam);
NET_ITS_PLATE_RESULT* struITSPlateResult = (NET_ITS_PLATE_RESULT*)(wParam);
//NET_ITS_PLATE_RESULT struITSPlateResult = wParam;
// 进行数据保存操作
if (struSetupParam.byAlarmInfoType == 1)
{
int i = 0;
for (i = 0; i < struITSPlateResult->dwPicNum; i++)
{
if (i >= sizeof(struITSPlateResult->struPicInfo) / sizeof(struITSPlateResult->struPicInfo[0])) {
break;
}
//printf("车牌号: %s\n", struITSPlateResult->struPlateInfo.sLicense);//车牌号
m_card.SetWindowTextA(struITSPlateResult->struPlateInfo.sLicense);
switch (struITSPlateResult->struPlateInfo.byColor)//车牌颜色
{
case VCA_BLUE_PLATE:
printf("车辆颜色: 蓝色\n");
break;
case VCA_YELLOW_PLATE:
printf("车辆颜色: 黄色\n");
break;
case VCA_WHITE_PLATE:
printf("车辆颜色: 白色\n");
break;
case VCA_BLACK_PLATE:
printf("车辆颜色: 黑色\n");
break;
default:
break;
}
//保存场景图
if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 1) || (struITSPlateResult->struPicInfo[i].byType == 2))
{
if (struITSPlateResult->struPicInfo[i].pBuffer != NULL) {
sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
fSnapPic = fopen(filename, "wb");
fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPic);
iNum++;
fclose(fSnapPic);
ShowImage(filename, 1);
}
}
//车牌小图片
if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 0))
{
if (struITSPlateResult->struPicInfo[i].pBuffer != NULL)
{
sprintf(filename, "testPicPlate%d_%d.jpg", iNum, i);
fSnapPicPlate = fopen(filename, "wb");
fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPicPlate);
iNum++;
fclose(fSnapPicPlate);
ShowImage(filename, 0);
}
}
//其他信息处理......
}
// 释放内存
//delete[] struITSPlateResult;
}
return 0;
}
void CHKMFCcardDlg::ShowImage(const CString& filename, int type)
{
float cx, cy, dx, dy, k, t;//跟控件的宽和高以及图片宽和高有关的参数
CRect rect;//用于获取图片控件的宽和高
CImage q;//为cimage图片类创建一个对象
q.Load(filename);//构造函数的形参是所加载图片的路径
cx = q.GetWidth();
cy = q.GetHeight();//获取图片的宽 高
k = cy / cx;//获得图片的宽高比
CWnd *pWnd = NULL;
if (type == 1)
{
pWnd = GetDlgItem(IDC_BigPic);//获取控件句柄
}
else
{
pWnd = GetDlgItem(IDC_SmallPic);//获取控件句柄
}
pWnd->GetClientRect(&rect);//获取Picture Control控件的客户区
dx = rect.Width();
dy = rect.Height();//获得控件的宽高比
t = dy / dx;//获得控件的宽高比
if (k >= t)
{
rect.right = floor(rect.bottom / k);
rect.left = (dx - rect.right) / 2;
rect.right = floor(rect.bottom / k) + (dx - rect.right) / 2;
}
else
{
rect.bottom = floor(k*rect.right);
rect.top = (dy - rect.bottom) / 2;
rect.bottom = floor(k*rect.right) + (dy - rect.bottom) / 2;
}
CDC *pDc = NULL;
pDc = pWnd->GetDC();//获取picture control的DC
int ModeOld = SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);//设置指定设备环境中的位图拉伸模式
//GetDlgItem(IDC_BigPic)->ShowWindow(FALSE);
//GetDlgItem(IDC_BigPic)->ShowWindow(TRUE);
GetDlgItem(IDC_SmallPic)->ShowWindow(FALSE);
GetDlgItem(IDC_SmallPic)->ShowWindow(TRUE);
q.StretchBlt(pDc->m_hDC, rect, SRCCOPY);//显示函数
SetStretchBltMode(pDc->m_hDC, ModeOld);
ReleaseDC(pDc);//释放指针空间
}
四、源代码
HKMCcard.h
// HKMFCcard.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
#include "HCNetSDK.h"
#define WM_SAVE_DATA (WM_USER + 100) //自定义消息
// CHKMFCcardApp:
// 有关此类的实现,请参阅 HKMFCcard.cpp
//
class CHKMFCcardApp : public CWinApp
{
public:
CHKMFCcardApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CHKMFCcardApp theApp;
HKMCcard.cpp
// HKMFCcard.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "HKMFCcard.h"
#include "HKMFCcardDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CHKMFCcardApp
BEGIN_MESSAGE_MAP(CHKMFCcardApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CHKMFCcardApp 构造
CHKMFCcardApp::CHKMFCcardApp()
{
// 支持重新启动管理器
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CHKMFCcardApp 对象
CHKMFCcardApp theApp;
// CHKMFCcardApp 初始化
BOOL CHKMFCcardApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 创建 shell 管理器,以防对话框包含
// 任何 shell 树视图控件或 shell 列表视图控件。
CShellManager *pShellManager = new CShellManager;
// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("山东力山特智能科技股份有限公司"));
NET_DVR_Init(); // init DVR
CHKMFCcardDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
}
// 删除上面创建的 shell 管理器。
if (pShellManager != NULL)
{
delete pShellManager;
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
HKMFCcardDlg.h
// HKMFCcardDlg.h : 头文件
//
#pragma once
#include "afxwin.h"
#include "afxcmn.h"
// CHKMFCcardDlg 对话框
class CHKMFCcardDlg : public CDialogEx
{
// 构造
public:
CHKMFCcardDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_HKMFCCARD_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
void ShowImage(const CString& filename, int type);
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnSaveData(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
CStatic m_textLogin;
CStatic m_textBufang;
CStatic m_bigPic;
CStatic m_smallPic;
CStatic m_card;
};
HMFCcardDlg.cpp
// HKMFCcardDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "HKMFCcard.h"
#include "HKMFCcardDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
int iNum = 0;
NET_DVR_SETUPALARM_PARAM struSetupParam = { 0 };
void CALLBACK cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
#if 1
HWND hWnd = FindWindow(NULL, _T("车牌号识别系统"));
//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。
switch (lCommand)
{
case COMM_UPLOAD_PLATE_RESULT:
{
//NET_DVR_PLATE_RESULT struPlateResult = { 0 };
//memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
NET_DVR_PLATE_RESULT *struPlateResult = { 0 };
memcpy(struPlateResult, pAlarmInfo, sizeof(*struPlateResult));
if (hWnd != NULL)
{
SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)((void *)struPlateResult), 0);
}
break;
}
case COMM_ITS_PLATE_RESULT:
{
NET_ITS_PLATE_RESULT struITSPlateResult = { 0 };
memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));
if (/*AfxGetMainWnd()->m_hWnd*/hWnd != NULL)
{
SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)(&struITSPlateResult), 0);
}
break;
}
default:
break;
}
#else
int i = 0;
char filename[100];
FILE *fSnapPic = NULL;
FILE *fSnapPicPlate = NULL;
//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。
switch (lCommand)
{
case COMM_UPLOAD_PLATE_RESULT:
{
NET_DVR_PLATE_RESULT struPlateResult = { 0 };
memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
printf("车牌号: %s\n", struPlateResult.struPlateInfo.sLicense);//车牌号
switch (struPlateResult.struPlateInfo.byColor)//车牌颜色
{
case VCA_BLUE_PLATE:
printf("车辆颜色: 蓝色\n");
break;
case VCA_YELLOW_PLATE:
printf("车辆颜色: 黄色\n");
break;
case VCA_WHITE_PLATE:
printf("车辆颜色: 白色\n");
break;
case VCA_BLACK_PLATE:
printf("车辆颜色: 黑色\n");
break;
default:
break;
}
//场景图
if (struPlateResult.dwPicLen != 0 && struPlateResult.byResultType == 1)
{
sprintf(filename, "testpic_%d.jpg", iNum);
fSnapPic = fopen(filename, "wb");
fwrite(struPlateResult.pBuffer1, struPlateResult.dwPicLen, 1, fSnapPic);
iNum++;
fclose(fSnapPic);
}
//车牌图
if (struPlateResult.dwPicPlateLen != 0 && struPlateResult.byResultType == 1)
{
sprintf(filename, "testPicPlate_%d.jpg", iNum);
fSnapPicPlate = fopen(filename, "wb");
fwrite(struPlateResult.pBuffer1, struPlateResult.dwPicLen, 1, fSnapPicPlate);
iNum++;
fclose(fSnapPicPlate);
}
//其他信息处理......
break;
}
case COMM_ITS_PLATE_RESULT:
{
NET_ITS_PLATE_RESULT struITSPlateResult = { 0 };
memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));
for (i = 0; i < struITSPlateResult.dwPicNum; i++)
{
printf("车牌号: %s\n", struITSPlateResult.struPlateInfo.sLicense);//车牌号
switch (struITSPlateResult.struPlateInfo.byColor)//车牌颜色
{
case VCA_BLUE_PLATE:
printf("车辆颜色: 蓝色\n");
break;
case VCA_YELLOW_PLATE:
printf("车辆颜色: 黄色\n");
break;
case VCA_WHITE_PLATE:
printf("车辆颜色: 白色\n");
break;
case VCA_BLACK_PLATE:
printf("车辆颜色: 黑色\n");
break;
default:
break;
}
//保存场景图
if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) && (struITSPlateResult.struPicInfo[i].byType == 1) || (struITSPlateResult.struPicInfo[i].byType == 2))
{
sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
fSnapPic = fopen(filename, "wb");
fwrite(struITSPlateResult.struPicInfo[i].pBuffer, struITSPlateResult.struPicInfo[i].dwDataLen, 1, fSnapPic);
iNum++;
fclose(fSnapPic);
}
//车牌小图片
if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) && (struITSPlateResult.struPicInfo[i].byType == 0))
{
sprintf(filename, "testPicPlate%d_%d.jpg", iNum, i);
fSnapPicPlate = fopen(filename, "wb");
fwrite(struITSPlateResult.struPicInfo[i].pBuffer, struITSPlateResult.struPicInfo[i].dwDataLen, 1, fSnapPicPlate);
iNum++;
fclose(fSnapPicPlate);
}
//其他信息处理......
}
break;
}
default:
break;
}
return;
#endif
return;
}
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CHKMFCcardDlg 对话框
CHKMFCcardDlg::CHKMFCcardDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CHKMFCcardDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CHKMFCcardDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LOGIN, m_textLogin);
DDX_Control(pDX, IDC_BUFANG, m_textBufang);
DDX_Control(pDX, IDC_BigPic, m_bigPic);
DDX_Control(pDX, IDC_SmallPic, m_smallPic);
DDX_Control(pDX, IDC_CARD, m_card);
}
BEGIN_MESSAGE_MAP(CHKMFCcardDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_SAVE_DATA, &CHKMFCcardDlg::OnSaveData)
ON_BN_CLICKED(IDC_BUTTON1, &CHKMFCcardDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// CHKMFCcardDlg 消息处理程序
BOOL CHKMFCcardDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_textLogin.SetWindowTextA("登录无状态");
m_textBufang.SetWindowTextA("布防无状态");
//---------------------------------------
//注册设备
//登录参数,包括设备地址、登录用户、密码等
LONG lUserID = -1;
NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 };
struLoginInfo.bUseAsynLogin = 0; //同步登录方式
strcpy(struLoginInfo.sDeviceAddress, "192.168.1.64"); //设备IP地址
struLoginInfo.wPort = 8000; //设备服务端口
strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名
strcpy(struLoginInfo.sPassword, "lst686868"); //设备登录密码
//设备信息, 输出参数
NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 };
lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
if (lUserID < 0)
{
/*printf("Login failed, error code: %d\n", NET_DVR_GetLastError());*/
m_textLogin.SetWindowTextA("登录失败");
NET_DVR_Cleanup();
return 0;
}
m_textLogin.SetWindowTextA("登录成功");
//---------------------------------------
//报警布防
//设置报警回调函数
/*注:多台设备对接时也只需要调用一次设置一个回调函数,不支持不同设备的事件在不同的回调函数里面返回*/
NET_DVR_SetDVRMessageCallBack_V50(0, cbMessageCallback, NULL);
//启用布防
struSetupParam.dwSize = sizeof(NET_DVR_SETUPALARM_PARAM);
struSetupParam.byLevel = 1; //布防优先级:0- 一等级(高),1- 二等级(中)
struSetupParam.byAlarmInfoType = 1; //上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
LONG lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, &struSetupParam);
if (lHandle < 0)
{
//printf("NET_DVR_SetupAlarmChan_V41 failed, error code: %d\n", NET_DVR_GetLastError());
m_textBufang.SetWindowTextA("布防失败");
NET_DVR_Logout(lUserID);
NET_DVR_Cleanup();
return 0;
}
m_textBufang.SetWindowTextA("布防成功");
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CHKMFCcardDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CHKMFCcardDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CHKMFCcardDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CHKMFCcardDlg::OnBnClickedButton1()
{
}
//数据的存储与显示
LRESULT CHKMFCcardDlg::OnSaveData(WPARAM wParam, LPARAM lParam)
{
// 在这里处理数据保存操作
// 例如,将 lParam 解释为指向数据的指针
char filename[100];
FILE *fSnapPic = NULL;
FILE *fSnapPicPlate = NULL;
//NET_ITS_PLATE_RESULT* struITSPlateResult = reinterpret_cast<NET_ITS_PLATE_RESULT*>(lParam);
NET_ITS_PLATE_RESULT* struITSPlateResult = (NET_ITS_PLATE_RESULT*)(wParam);
//NET_ITS_PLATE_RESULT struITSPlateResult = wParam;
// 进行数据保存操作
if (struSetupParam.byAlarmInfoType == 1)
{
int i = 0;
for (i = 0; i < struITSPlateResult->dwPicNum; i++)
{
if (i >= sizeof(struITSPlateResult->struPicInfo) / sizeof(struITSPlateResult->struPicInfo[0])) {
break;
}
//printf("车牌号: %s\n", struITSPlateResult->struPlateInfo.sLicense);//车牌号
m_card.SetWindowTextA(struITSPlateResult->struPlateInfo.sLicense);
switch (struITSPlateResult->struPlateInfo.byColor)//车牌颜色
{
case VCA_BLUE_PLATE:
printf("车辆颜色: 蓝色\n");
break;
case VCA_YELLOW_PLATE:
printf("车辆颜色: 黄色\n");
break;
case VCA_WHITE_PLATE:
printf("车辆颜色: 白色\n");
break;
case VCA_BLACK_PLATE:
printf("车辆颜色: 黑色\n");
break;
default:
break;
}
//保存场景图
if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 1) || (struITSPlateResult->struPicInfo[i].byType == 2))
{
if (struITSPlateResult->struPicInfo[i].pBuffer != NULL) {
sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
fSnapPic = fopen(filename, "wb");
fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPic);
iNum++;
fclose(fSnapPic);
ShowImage(filename, 1);
}
}
//车牌小图片
if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 0))
{
if (struITSPlateResult->struPicInfo[i].pBuffer != NULL)
{
sprintf(filename, "testPicPlate%d_%d.jpg", iNum, i);
fSnapPicPlate = fopen(filename, "wb");
fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPicPlate);
iNum++;
fclose(fSnapPicPlate);
ShowImage(filename, 0);
}
}
//其他信息处理......
}
// 释放内存
//delete[] struITSPlateResult;
}
return 0;
}
void CHKMFCcardDlg::ShowImage(const CString& filename, int type)
{
float cx, cy, dx, dy, k, t;//跟控件的宽和高以及图片宽和高有关的参数
CRect rect;//用于获取图片控件的宽和高
CImage q;//为cimage图片类创建一个对象
q.Load(filename);//构造函数的形参是所加载图片的路径
cx = q.GetWidth();
cy = q.GetHeight();//获取图片的宽 高
k = cy / cx;//获得图片的宽高比
CWnd *pWnd = NULL;
if (type == 1)
{
pWnd = GetDlgItem(IDC_BigPic);//获取控件句柄
}
else
{
pWnd = GetDlgItem(IDC_SmallPic);//获取控件句柄
}
pWnd->GetClientRect(&rect);//获取Picture Control控件的客户区
dx = rect.Width();
dy = rect.Height();//获得控件的宽高比
t = dy / dx;//获得控件的宽高比
if (k >= t)
{
rect.right = floor(rect.bottom / k);
rect.left = (dx - rect.right) / 2;
rect.right = floor(rect.bottom / k) + (dx - rect.right) / 2;
}
else
{
rect.bottom = floor(k*rect.right);
rect.top = (dy - rect.bottom) / 2;
rect.bottom = floor(k*rect.right) + (dy - rect.bottom) / 2;
}
CDC *pDc = NULL;
pDc = pWnd->GetDC();//获取picture control的DC
int ModeOld = SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);//设置指定设备环境中的位图拉伸模式
//GetDlgItem(IDC_BigPic)->ShowWindow(FALSE);
//GetDlgItem(IDC_BigPic)->ShowWindow(TRUE);
GetDlgItem(IDC_SmallPic)->ShowWindow(FALSE);
GetDlgItem(IDC_SmallPic)->ShowWindow(TRUE);
q.StretchBlt(pDc->m_hDC, rect, SRCCOPY);//显示函数
SetStretchBltMode(pDc->m_hDC, ModeOld);
ReleaseDC(pDc);//释放指针空间
}
五、改进
1.添加用户管理
2.历史记录,数据库中添加图片字段,点击查看
3.实时记录
4.用户的操作记录
5.图片备份,时间久了存到备份盘中
6.添加录入数据库中没有的车牌号
7.添加车牌号对比之后自动开关门
8.接受库管传来的车辆信息
9.将车牌信息传递给库管
posted on 2024-10-15 16:08 ZanderChan 阅读(2247) 评论(1) 收藏 举报






浙公网安备 33010602011771号