using AForge.Video.DirectShow; using libzkfpcsharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Windows.Forms; using Sample; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using log4net.Repository.Hierarchy; namespace ICS { public partial class FingerPrintForm : Form { // 指纹采集设备 IntPtr fingerPrintDevHandle = IntPtr.Zero; // 本窗口的句柄 用于显示指纹图像 IntPtr formHandle = IntPtr.Zero; // 指纹数据库的句柄 用于判断执行指纹模板数据的相关API IntPtr dbHandle = IntPtr.Zero; // 采集线程工作标志位 bool captureWorking = false; bool threadExit = false; // 小窗口显示指纹图像 byte[] fpImgBuffer; // 已经采集的次数 int RegisterCount = 0; // 需要采集测次数 const int REGISTER_ROUND = 3; // 当前DB中保存的指纹ID int fingerId = 1; // 每次采集的指纹模板数据 byte[][] regTmps; // 合并后的指纹模板数据 byte[] regTmp; // 单次采集的指纹模板数据 byte[] capTmp; // 单次采集的指纹模板数据长度 最长为2048个字节 int cbCapTmp = 0; // 合并后的指纹模板数据长度 int cbRegTmp = 0; // 指纹图像宽度和高度 private int fpWidth = 0; private int fpHeight = 0; // 采集线程 Thread captureThread = null; const int MESSAGE_CAPTURED_OK = 0x0400 + 6; public static log4net.ILog log = log4net.LogManager.GetLogger("ICS"); public bool CaptureWorking { get => captureWorking; set => captureWorking = value; } public bool ThreadExit { get => threadExit; set => threadExit = value; } public int FingerId { get => fingerId; set => fingerId = value; } [DllImport("user32.dll", EntryPoint = "SendMessageA")] public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); public FingerPrintForm() { InitializeComponent(); } /// <summary> /// 打开指纹采集设备 /// </summary> /// <param name="index"></param> /// <returns></returns> public int OpenFingerDevice(int index) { fingerPrintDevHandle = zkfp2.OpenDevice(index); if (fingerPrintDevHandle == IntPtr.Zero) { // 指纹设备打开失败 return -1; } else { dbHandle = zkfp2.DBInit(); if (dbHandle == IntPtr.Zero) { // 数据库初始化失败 return -2; } else { fingerId = 1; return 0; } } } /// <summary> /// 关闭指纹采集设备 /// </summary> /// <param name="index"></param> public void CloseFingerDevice(int index) { // 关闭设备 if (IntPtr.Zero!= fingerPrintDevHandle) { zkfp2.DBFree(dbHandle); dbHandle = IntPtr.Zero; zkfp2.CloseDevice(fingerPrintDevHandle); fingerPrintDevHandle= IntPtr.Zero; } } /// <summary> /// 开始采集指纹 /// </summary> /// <param name="round"></param> public void StartCaptureFingerPrint() { if (IntPtr.Zero == fingerPrintDevHandle) { this.labelTips.Text = "设备还未初始化"; JObject obj = new JObject { { "command", "CaptureFingerPrint" }, { "success", "false" }, { "message", "device not initialized" } }; Form1.SendMsgToClient("CapFingerPrint", JsonConvert.SerializeObject(obj)); return; } this.labelTips.Text = "请用同一个手指按压3次"; System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FingerPrintForm)); this.picFingerPrint.Image = ((System.Drawing.Image)(resources.GetObject("picFingerPrint.Image"))); // 读取参数中的指纹图像宽度和高度 byte[] paramValue = new byte[4]; int size = 4; zkfp2.GetParameters(fingerPrintDevHandle, 1, paramValue, ref size); zkfp2.ByteArray2Int(paramValue, ref fpWidth); zkfp2.GetParameters(fingerPrintDevHandle, 2, paramValue, ref size); zkfp2.ByteArray2Int(paramValue, ref fpHeight); // 生成指纹图像字节数组 fpImgBuffer = new byte[fpWidth * fpHeight]; regTmps = new byte[REGISTER_ROUND][]; for (int i = 0; i < REGISTER_ROUND; i++) { regTmps[i] = new byte[2048]; } regTmp = new byte[2048]; capTmp = new byte[2048]; this.RegisterCount = 0; // 开启采集线程 captureThread = new Thread(new ThreadStart(DoCapture)); ThreadExit = false; captureThread.IsBackground = true; captureThread.Start(); // 采集工作线程标志位 CaptureWorking = true; } public void StopCaptureFingerPrint() { // 停止工作 CaptureWorking = false; // 停止线程 ThreadExit = true; // this.Hide(); } /// <summary> /// 执行采集指纹动作 /// </summary> private void DoCapture() { while (ThreadExit == false) { if (CaptureWorking == true) { int ret = zkfp2.AcquireFingerprint(fingerPrintDevHandle, fpImgBuffer, capTmp, ref cbCapTmp); if (ret == zkfp.ZKFP_ERR_OK) { SendMessage(formHandle, MESSAGE_CAPTURED_OK, IntPtr.Zero, IntPtr.Zero); } Thread.Sleep(200); } } } protected override void DefWndProc(ref Message m) { switch (m.Msg) { case MESSAGE_CAPTURED_OK: { MemoryStream ms = new MemoryStream(); BitmapFormat.GetBitmap(fpImgBuffer, fpWidth, fpHeight, ref ms); Bitmap bmp = new Bitmap(ms); this.picFingerPrint.Image = bmp; JObject obj = new JObject { { "command", "CaptureFingerPrint" }, { "image", "data:image/bmp;base64," + Form1.ToBase64(bmp) } }; // 第一次采集 if (RegisterCount == 0) { Array.Copy(capTmp, regTmps[RegisterCount], cbCapTmp); // 判断是否在数据库中有重复的指纹 // 仅在第一次采集时判断重复 后续会调用DBMatch判断是否与第一次采集的指纹为同一手指 int fid = 0; int score = 0; int identifyRet = zkfp2.DBIdentify(dbHandle, capTmp, ref fid, ref score); if (identifyRet == 0 && fid > 0) { // 找到本次采集已经保存的指纹 obj.Add("success", "false"); obj.Add("message", "fingerPrint found"); this.labelTips.Text = "数据库中找到相同的手指" + fid + "\r\n请用不同手指再按压" + (REGISTER_ROUND - RegisterCount) + "次"; } else { // 数据库中没有找到 进行下一次采集 RegisterCount++; obj.Add("success", "true"); obj.Add("pressLeft", REGISTER_ROUND - RegisterCount); this.labelTips.Text = "请再按压" + (REGISTER_ROUND - RegisterCount) + "次"; } } else { int matchRet = zkfp2.DBMatch(dbHandle, capTmp, regTmps[RegisterCount - 1]); if (matchRet <= 0) { // 本次采集的指纹与上次采集的指纹不是同一个手指 提示 obj.Add("success", "false"); obj.Add("code", matchRet); obj.Add("pressLeft", REGISTER_ROUND - RegisterCount); this.labelTips.Text = "与上一次的手指不同\r\n请用同一手指再按压" + (REGISTER_ROUND - RegisterCount) + "次"; } else { Array.Copy(capTmp, regTmps[RegisterCount], cbCapTmp); RegisterCount++; obj.Add("success", "true"); obj.Add("pressLeft", REGISTER_ROUND - RegisterCount); // 一枚指纹的3次采集结束 if (RegisterCount >= REGISTER_ROUND) { // 合并3次指纹 int mergeRet = zkfp2.DBMerge(dbHandle, regTmps[0], regTmps[1], regTmps[2], regTmp, ref cbRegTmp); if (mergeRet == zkfperrdef.ZKFP_ERR_OK) { // 采集成功后将指纹保存到数据库中 zkfp2.DBAdd(dbHandle, FingerId, regTmp); StopCaptureFingerPrint(); FingerId++; obj.Add("tempLen", cbRegTmp); obj.Add("tempData", zkfp2.BlobToBase64(regTmp, cbRegTmp)); this.labelTips.Text = "指纹采集成功"; log.Info("指纹采集成功"); } else { obj.Remove("success"); obj.Add("success", "false"); obj.Add("code", mergeRet); } } else { this.labelTips.Text = "请再按压" + (REGISTER_ROUND - RegisterCount) + "次"; } } } Form1.SendMsgToClient("CapFingerPrint", JsonConvert.SerializeObject(obj)); break; } default: { base.DefWndProc(ref m); break; } } } private void FingerPrintForm_Load(object sender, EventArgs e) { formHandle = this.Handle; } } }