using EC.AutoWeightServer.Center; using EC.AutoWeightServer.Model.Config; using EC.AutoWeightServer.Model.EventArgsEx; using EC.AutoWeightServer.SDK; using EC.Service.Transport; using EC.Utils; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Windows.Forms; namespace EC.AutoWeightServer.UI.UC { public partial class UCLicensePlate : UserControl { #region SDK 变量 /// /// 相机 IP /// private string _ip; /// /// 相机 _port /// private ushort _port; private string _username; private string _password; /// /// 相机操作句柄 /// private int _deviceHandle = 0; /// /// 相机播放句柄 /// private int _playHandle = 0; private VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK PlateResultCB { get; set; } = null; #endregion SDK 变量 public UCLicensePlate() { InitializeComponent(); } #region init & close public void InitForm(string ip, ushort port, string username, string password) { VzClientSDK.VzLPRClient_Setup(); _ip = ip; _port = port; _username = username; _password = password; } /// /// 关闭 /// public void CloseForm() { timeAuto.Enabled = false; _ip = string.Empty; _port = 0; _username = string.Empty; _password = string.Empty; ClosePlayHandle(); CloseDeviceHandle(); VzClientSDK.VzLPRClient_Cleanup(); } #endregion init & close #region 组件操作响应事件 private void Btn_Man_Click(object sender, EventArgs e) { ForceTrigger(); } /// /// 定时检测相机状态 /// /// /// private void TimAuto_Tick(object sender, EventArgs e) { if (!IsDeviceConnected()) OpenDevice(); if (!IsPlayConnected()) OpenPlay(); } #endregion 组件操作响应事件 #region get & set public int GetDateTime() { var info = new VzClientSDK.VZ_DATE_TIME_INFO(); var ret = VzClientSDK.VzLPRClient_GetDateTime(_deviceHandle, ref info); return ret; } public int SetDateTime() { return 1; } public void SetBtnManVisible(bool able) { this.btnMan.Visible = able; } #endregion get & set #region tool methods /// /// 打开相机连接 /// /// public bool OpenDevice() { _deviceHandle = OpenDeviceHandle(); timeAuto.Enabled = true; if (!IsDeviceConnected()) { LogUnit.Info("打开设备" + _ip + "失败"); return false; } LogUnit.Info("打开设备" + _ip + "成功!"); return OpenPlay(); } /// /// 打开相机监控 /// /// private bool OpenPlay() { if (!IsDeviceConnected()) return false; pictureBox.Image = null; SetVzClientCallBack(null, 0); ClosePlayHandle(); _playHandle = OpenPlayHandle(); PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult); SetVzClientCallBack(PlateResultCB, 1); timeAuto.Enabled = true; LogUnit.Info("开始读取车牌"); return IsPlayConnected(); } /// /// 返回相机操作句柄 /// /// private int OpenDeviceHandle() { return VzClientSDK.VzLPRClient_Open(_ip, _port, _username, _password); } /// /// 关闭相机操作句柄 /// /// private bool CloseDeviceHandle() { if (!IsDeviceConnected()) return true; var ret = VzClientSDK.VzLPRClient_Close(_deviceHandle); if (!ret.Equals(0)) return false; _deviceHandle = 0; return true; } /// /// 返回相机播放句柄 /// /// private int OpenPlayHandle() { if (!IsDeviceConnected()) return 0; return VzClientSDK.VzLPRClient_StartRealPlay(_deviceHandle, pictureBox.Handle); } /// /// 停止相机播放句柄 /// /// private bool ClosePlayHandle() { if (!IsPlayConnected()) return true; var ret = VzClientSDK.VzLPRClient_StopRealPlay(_playHandle); if (!ret.Equals(0)) return false; _playHandle = 0; return true; } /// /// 手动识别 /// /// public bool ForceTrigger() { if (!IsDeviceConnected()) return false; var ret = VzClientSDK.VzLPRClient_ForceTrigger(_deviceHandle); return ret.Equals(0); } /// /// 截图 /// /// public string GetPlatePic(string license) { if (!IsDeviceConnected() || !IsPlayConnected()) return string.Empty; var path = PhotoService.GetSaveImagePath(license); var ret = VzClientSDK.VzLPRClient_GetSnapShootToJpeg2(_playHandle, path, 90); return ret.Equals(0) ? path : string.Empty; } /// /// func 识别结果回调函数 /// bEnableImage 指定识别结果的回调是否需要包含截图信息:1为需要,0为不需要 /// /// /// /// private bool SetVzClientCallBack(VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK func, int bEnableImage) { if (!IsDeviceConnected()) return false; var ret = VzClientSDK.VzLPRClient_SetPlateInfoCallBack(_deviceHandle, func, IntPtr.Zero, bEnableImage); return ret.Equals(0); } /// /// 获取相机连接状态,判断 _deviceHandle 是否有效 /// /// public bool IsDeviceConnected() { if (_deviceHandle == -1) return false; if (_deviceHandle <= 0) return false; byte stat = 0; var ret = VzClientSDK.VzLPRClient_IsConnected(_deviceHandle, ref stat); return (ret.Equals(0) && stat.Equals(1)); } /// /// 获取相机播放状态,判断 _playHandle 是否有效 /// /// public bool IsPlayConnected() { if (!IsDeviceConnected()) return false; if (_playHandle <= 0) return false; return true; } #endregion tool methods #region 向外暴露一个可以处理 抓获车牌结果 的委托 /// /// 处理相机结果的回调事件 /// /// /// /// /// /// /// /// /// private int OnPlateResult(int handle, IntPtr pUserData, IntPtr pResult, uint uNumPlates, VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType, IntPtr pImgFull, IntPtr pImgPlateClip) { //如果是实时识别结果,则return,需要稳定识别结果 if (eResultType == VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME) return -1; var result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult)); var strLicense = new string(result.license).Replace("\0", ""); var strColor = new string(result.color).Replace("\0", ""); strLicense = PretreatPlate(strLicense); //判断识别车牌是否为正常车牌 if (!CommonUtil.IsSuccessPlate(strLicense)) return -1; //判断定时手动检测结果 if (eResultType == VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_FORCE_TRIGGER) { var truck = ServiceCenter.TruckService.SelectEntityByWhere($"LicensePlate = '{strLicense}'"); if (truck == null) return -1; } var path = PhotoService.GetSaveImagePath(strLicense);// strFilePath + fileName; VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 100); LogUnit.Info("车牌 " + strLicense + " " + strColor + " " + path); // 添加 向外暴露的 处理相机结果 的函数 PlateCallBack(strLicense, strColor, path); return 0; } private void PlateCallBack(string plate, string platecolor, string filename) { PlateInfoCallBack?.Invoke(this, new PlateEventArgs(plate, platecolor, filename)); } /// /// 一个可以处理 抓获车牌结果 的事件 /// public event EventHandler PlateInfoCallBack; //定义一个委托类型的事件 #endregion 向外暴露一个可以处理 抓获车牌结果 的委托 #region Other /// /// 车牌预处理 /// public string PretreatPlate(string oldPlate) { oldPlate = oldPlate.ToUpper(); if (oldPlate.Length < 7) return oldPlate; var newPlate = oldPlate.Length > 7 ? oldPlate.Substring(0, 7) : oldPlate; if (ServerConfig.IsPretreatPlate > 0) { var dict = new Dictionary { { "O", "0" }, { "I", "1" } }; newPlate = SubRepString(newPlate, 3, newPlate.Length, dict); dict = new Dictionary { { "D", "0" } }; newPlate = SubRepString(newPlate, newPlate.Length - 3, newPlate.Length, dict); } return newPlate; } public string SubRepString(string str, int start, int end, Dictionary dict) { var beforeStr = str.Substring(0, start); var changeStr = str.Substring(start, end - start); var afterStr = str.Substring(end, str.Length - end); foreach (var key in dict.Keys) { changeStr = changeStr.Replace(key, dict[key]); } return beforeStr + changeStr + afterStr; } #endregion Other } }