中控指纹采集器java版本
具体实现官网已经给了demo,可以自行看下。接下来是我在此基础上将demo改成接口的形式,供页面调用。
指纹采集页面:
效果图:
代码概述:
1、去除原demo线程中的sleep,采用手动录入重新获取指纹图片的模式。
2、提供三个接口,初始化设备,重新录入(关闭设备,然后开启设备),获取指纹(获取指纹采集生成的图片)
3、生成指纹图片到本地
4、finger文件夹下目前只保存一个,每次生成新图片之前删除已存在的图片
注:下方代码仅供参考,具体实现请以自身开发环境而定(3、4步请根据自身情况而定。由于我暂时不做电子存档,所以没有存指纹图片以及关联业务)
package com.jinmdz.fmis.api.api.controller;
import com.zkteco.biometric.FingerprintSensorErrorCode;
import com.zkteco.biometric.FingerprintSensorEx;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author lvyq
* @version 1.0 指纹采集
* @description: TODO
* @date 2020/11/24 17:50
*/
@RestController
@RequestMapping("/zk")
public class ZKFingerController {
int fpWidth = 0;
int fpHeight = 0;
private byte[] lastRegTemp = new byte[2048];
private int cbRegTemp = 0;
private byte[][] regtemparray = new byte[3][2048];
private boolean bRegister = false;
private boolean bIdentify = true;
private int iFid = 1;
private int nFakeFunOn = 1;
private int enroll_idx = 0;
private byte[] imgbuf = null;
private byte[] template = new byte[2048];
private int[] templateLen = new int[1];
private boolean mbStop = true;
private long mhDevice = 0;
private long mhDB = 0;
private WorkThread workThread = null;
private JTextArea textArea;
/**
* @description: 打开指纹采集
* @author: lvyq
* @date: 2020/11/24 17:52
* @version 1.0
*/
@RequestMapping("/fingerInit")
private Object ZKFingerInit() {
Map map = new HashMap<>();
String msg = initFinger();
map.put("state", true);
map.put("msg", msg);
return map;
}
/**
* @description: 重新录入
* @author: lvyq
* @date: 2020/11/25 17:50
* @version 1.0
*/
@RequestMapping("/reFinger")
public Object reFinger() {
Map map = new HashMap<>();
//关闭
FreeSensor();
//开启
String msg = initFinger();
map.put("state", true);
map.put("msg", msg);
return map;
}
/**
* @description: 获取指纹图片
* @author: lvyq
* @date: 2020/11/25 17:51
* @version 1.0
*/
@RequestMapping("/getFingerImg")
public Object getFingerImg(HttpServletRequest request) {
Map map = new HashMap<>();
String path = "E:\\finger\\";
File file = new File(path);
try {
String newPath = path + file.listFiles()[0].getName();
File newFile = new File(newPath);
String fingerName = newFile.getName();
map.put("state", true);
//文件网络路径,供前端回显,此处仅供参考
map.put("imgUrl", "http://127.0.0.1:80/finger/fingerName");
//文件相对地址,前端使用-保存数据库
map.put("imgPath", "/finger/fingerName");
} catch (Exception e) {
map.put("code", 0);
map.put("data", null);
map.put("msg", "暂无图片");
return map;
}
return map;
}
private String OnExtractOK(byte[] template, int len) {
String text = "";
if (bRegister) {
int[] fid = new int[1];
int[] score = new int[1];
int ret = FingerprintSensorEx.DBIdentify(mhDB, template, fid, score);
if (ret == 0) {
bRegister = false;
enroll_idx = 0;
return "手指已经注册" + fid[0] + ",取消注册";
}
if (enroll_idx > 0 && FingerprintSensorEx.DBMatch(mhDB, regtemparray[enroll_idx - 1], template) <= 0) {
return "请按同一个手指三次报名";
}
System.arraycopy(template, 0, regtemparray[enroll_idx], 0, 2048);
enroll_idx++;
if (enroll_idx == 3) {
int[] _retLen = new int[1];
_retLen[0] = 2048;
byte[] regTemp = new byte[_retLen[0]];
if (0 == (ret = FingerprintSensorEx.DBMerge(mhDB, regtemparray[0], regtemparray[1], regtemparray[2], regTemp, _retLen)) &&
0 == (ret = FingerprintSensorEx.DBAdd(mhDB, iFid, regTemp))) {
iFid++;
cbRegTemp = _retLen[0];
System.arraycopy(regTemp, 0, lastRegTemp, 0, cbRegTemp);
//String strBase64 = FingerprintSensorEx.BlobToBase64(regTemp, cbRegTemp);
return "注册成功";
} else {
return "注册失败,错误码" + ret;
}
} else {
text = "你需要按" + (3 - enroll_idx) + "次指纹";
}
} else {
if (bIdentify) {
int[] fid = new int[1];
int[] score = new int[1];
int ret = FingerprintSensorEx.DBIdentify(mhDB, template, fid, score);
if (ret == 0) {
text = "识别成功, fid=" + fid[0] + ",score=" + score[0];
} else {
text = "识别失败, errcode=" + ret;
}
} else {
if (cbRegTemp <= 0) {
text = "请先注册!";
} else {
int ret = FingerprintSensorEx.DBMatch(mhDB, lastRegTemp, template);
if (ret > 0) {
text = "验证成功, score=" + ret;
} else {
text = "验证失败,ret=" + ret;
}
}
}
}
return text;
}
private void FreeSensor() {
mbStop = true;
if (0 != mhDB) {
FingerprintSensorEx.DBFree(mhDB);
mhDB = 0;
}
if (0 != mhDevice) {
FingerprintSensorEx.CloseDevice(mhDevice);
mhDevice = 0;
}
FingerprintSensorEx.Terminate();
}
public static byte[] changeByte(int data) {
return intToByteArray(data);
}
public static byte[] intToByteArray(final int number) {
byte[] abyte = new byte[4];
abyte[0] = (byte) (0xff & number);
abyte[1] = (byte) ((0xff00 & number) >> 8);
abyte[2] = (byte) ((0xff0000 & number) >> 16);
abyte[3] = (byte) ((0xff000000 & number) >> 24);
return abyte;
}
public static int byteArrayToInt(byte[] bytes) {
int number = bytes[0] & 0xFF;
number |= ((bytes[1] << 8) & 0xFF00);
number |= ((bytes[2] << 16) & 0xFF0000);
number |= ((bytes[3] << 24) & 0xFF000000);
return number;
}
public static void writeBitmap(byte[] imageBuf, int nWidth, int nHeight, String path) throws IOException {
java.io.FileOutputStream fos = new java.io.FileOutputStream(path);
java.io.DataOutputStream dos = new java.io.DataOutputStream(fos);
/**
*。。。具体代码见demo。此处代码直接引用。无需修改。。
*/
fos.close();
}
private class WorkThread extends Thread {
@Override
public void run() {
super.run();
int ret = 0;
while (!mbStop) {
templateLen[0] = 2048;
if (0 == (ret = FingerprintSensorEx.AcquireFingerprint(mhDevice, imgbuf, template, templateLen))) {
if (nFakeFunOn == 1) {
byte[] paramValue = new byte[4];
int[] size = new int[1];
size[0] = 4;
int nFakeStatus = 0;
//GetFakeStatus
ret = FingerprintSensorEx.GetParameters(mhDevice, 2004, paramValue, size);
nFakeStatus = byteArrayToInt(paramValue);
System.out.println("ret = " + ret + ",nFakeStatus=" + nFakeStatus);
if (0 == ret && (byte) (nFakeStatus & 31) != 31) {
textArea.setText("Is a fake-finer?");
return;
}
}
OnCatpureOK(imgbuf);
OnExtractOK(template, templateLen[0]);
String strBase64 = FingerprintSensorEx.BlobToBase64(template, templateLen[0]);
System.out.println("strBase64=" + strBase64);
}
}
}
}
private void OnCatpureOK(byte[] imgBuf) {
try {
long dateTime = System.currentTimeMillis();
//删除图片文件
try {
String path = "E:\\finger\\";
File file = new File(path);
String newPath = path + file.listFiles()[0].getName();
File newFile = new File(newPath);
System.out.println("删除图片==" + file.getName() + "" + newFile.delete());
} catch (Exception e) {
e.printStackTrace();
} finally {
writeBitmap(imgBuf, fpWidth, fpHeight, "E:\\finger\\" + dateTime + ".bmp");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public String initFinger() {
if (0 != mhDevice) {
return "请先关闭设备";
}
int ret = FingerprintSensorErrorCode.ZKFP_ERR_OK;
cbRegTemp = 0;
bRegister = false;
bIdentify = false;
iFid = 1;
enroll_idx = 0;
if (FingerprintSensorErrorCode.ZKFP_ERR_OK != FingerprintSensorEx.Init()) {
return "初始化失败!";
}
ret = FingerprintSensorEx.GetDeviceCount();
if (ret < 0) {
FreeSensor();
return "没有设备连接!";
}
if (0 == (mhDevice = FingerprintSensorEx.OpenDevice(0))) {
FreeSensor();
return "打开设备失败,ret=" + ret + "!";
}
if (0 == (mhDB = FingerprintSensorEx.DBInit())) {
FreeSensor();
return "初始化数据库失败,ret=" + ret + "!";
}
//set fakefun off
FingerprintSensorEx.SetParameters(mhDevice, 2002, changeByte(nFakeFunOn), 4);
byte[] paramValue = new byte[4];
int[] size = new int[1];
//GetFakeOn
size[0] = 4;
FingerprintSensorEx.GetParameters(mhDevice, 2002, paramValue, size);
nFakeFunOn = byteArrayToInt(paramValue);
size[0] = 4;
FingerprintSensorEx.GetParameters(mhDevice, 1, paramValue, size);
fpWidth = byteArrayToInt(paramValue);
size[0] = 4;
FingerprintSensorEx.GetParameters(mhDevice, 2, paramValue, size);
fpHeight = byteArrayToInt(paramValue);
imgbuf = new byte[fpWidth * fpHeight];
mbStop = false;
workThread = new WorkThread();
workThread.start();// 启动线程*/
return "打开成功";
}
}
该示例仅为提供实现思路,且该示例为单击版,不支持联网,如需联网版,可自行修改,或换其它型号
ZKFinger Live20R 版对接java - B/S(联机版)https://blog.csdn.net/qq_27185879/article/details/125637890