海康门禁机设备API接口对接
引言:
我本人在对接海康门禁机设备的时候遇到了两个
- 问题1:人脸下发失败的问题,是根据官方的Demo,遇到的问题,可以参考一下
这个问题我排查了很久,最终发现是海康给的Demo里面的Json包是有问题的,json数据经过断点排查,发现请求下发的参数里面并无人脸信息
- 问题2:人员下发时候的照片是有规格要求的,图片大小200k以内,图片的裁剪比例要求,可以使用技术规避,人员照片规格要求(比如说清晰度,复杂背景,脸部位置问题,只能人员重新上传)
1. 人脸下发API解决
1.把原生Json包替换会hutool工具类的Json包
2.写一个工具类解决图片大小问题,图片裁剪比例问题
亲测可以用
/**
* 功能:按照二进制方式下发人脸图片
* @param userID 用户注册ID
* @param employeeNo 人员工号
* @throws JSONException
* @throws InterruptedException
*/
public static void addFaceByBinary(int userID, String employeeNo) throws JSONException, InterruptedException, IOException {
HCNetSDK.BYTE_ARRAY ptrByteArray = new HCNetSDK.BYTE_ARRAY(1024); // 数组
String strInBuffer = "PUT /ISAPI/Intelligent/FDLib/FDSetUp?format=json";
System.arraycopy(strInBuffer.getBytes(), 0, ptrByteArray.byValue, 0, strInBuffer.length()); // 字符串拷贝到数组中
ptrByteArray.write();
int lHandler = hCNetSDK.NET_DVR_StartRemoteConfig(userID, HCNetSDK.NET_DVR_FACE_DATA_RECORD, ptrByteArray.getPointer(), strInBuffer.length(), null, null);
if (lHandler < 0) {
System.out.println("Addface NET_DVR_StartRemoteConfig 失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
return;
} else {
System.out.println("Addface NET_DVR_StartRemoteConfig 成功!");
HCNetSDK.NET_DVR_JSON_DATA_CFG struAddFaceDataCfg = new HCNetSDK.NET_DVR_JSON_DATA_CFG();
struAddFaceDataCfg.read();
cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject();
jsonObject.set("faceLibType", "blackFD");
jsonObject.set("FDID", "1");
jsonObject.set("FPID", employeeNo); // 人脸下发关联的工号
String strJsonData = jsonObject.toString();
System.arraycopy(strJsonData.getBytes(), 0, ptrByteArray.byValue, 0, strJsonData.length()); // 字符串拷贝到数组中
ptrByteArray.write();
struAddFaceDataCfg.dwSize = struAddFaceDataCfg.size();
struAddFaceDataCfg.lpJsonData = ptrByteArray.getPointer();
struAddFaceDataCfg.dwJsonDataSize = strJsonData.length();
/*****************************************
* 从本地文件里面读取JPEG图片二进制数据
*****************************************/
FileInputStream picfile = null;
int picdataLength = 0;
byte[] picBytes = null;
try {
picfile = new FileInputStream(new File(".//pic//333.jpg"));
picdataLength = picfile.available();
picBytes = new byte[picdataLength];
picfile.read(picBytes);
picfile.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
if (picBytes == null || picBytes.length <= 0) {
System.out.println("input file dataSize < 0");
return;
}
File p1 = new File(".//pic//333.jpg");
byte[] imageBytes = FileUtil.readBytes(p1);
byte[] finBytes = ImageUtil.resizeImage(imageBytes, 600, 800);
// 压缩图片到200KB
byte[] compressedPicBytes = ImageUtil.compressPicForScale(finBytes, 200);
HCNetSDK.BYTE_ARRAY ptrpicByte = new HCNetSDK.BYTE_ARRAY(compressedPicBytes.length);
System.arraycopy(compressedPicBytes, 0, ptrpicByte.byValue, 0, compressedPicBytes.length);
ptrpicByte.write();
struAddFaceDataCfg.dwPicDataSize = compressedPicBytes.length;
struAddFaceDataCfg.lpPicData = ptrpicByte.getPointer();
struAddFaceDataCfg.write();
HCNetSDK.BYTE_ARRAY ptrOutuff = new HCNetSDK.BYTE_ARRAY(1024);
IntByReference pInt = new IntByReference(0);
while (true) {
int dwState = hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(lHandler, struAddFaceDataCfg.getPointer(), struAddFaceDataCfg.dwSize, ptrOutuff.getPointer(), 1024, pInt);
if (dwState == -1) {
System.out.println("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
break;
}
// 读取返回的json并解析
ptrOutuff.read();
String strResult = new String(ptrOutuff.byValue).trim();
System.out.println("dwState:" + dwState + ",strResult:" + strResult);
cn.hutool.json.JSONObject jsonResult = new cn.hutool.json.JSONObject(strResult);
int statusCode = jsonResult.getInt("statusCode");
if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) {
System.out.println("配置等待");
Thread.sleep(10);
continue;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) {
System.out.println("下发人脸失败, json retun:" + jsonResult.toString());
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) {
System.out.println("下发人脸异常, json retun:" + jsonResult.toString());
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) {
if (statusCode != 1) {
System.out.println("下发人脸成功,但是有异常情况:" + jsonResult.toString());
} else {
System.out.println("下发人脸成功, json retun:" + jsonResult.toString());
}
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) {
System.out.println("下发人脸完成");
break;
}
}
if (!hCNetSDK.NET_DVR_StopRemoteConfig(lHandler)) {
System.out.println("NET_DVR_StopRemoteConfig接口调用失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
} else {
System.out.println("NET_DVR_StopRemoteConfig接口成功");
}
}
}
package util;
import net.coobird.thumbnailator.Thumbnails;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* @Author rjx
* @Date 2024/7/05
*/
//@Slf4j
//@UtilityClass
public class ImageUtil {
/**
* 根据指定大小压缩图片
*
* @param imageBytes 源图片字节数组
* @param desFileSize 指定图片大小,单位kb
* @return 压缩质量后的图片字节数组
*/
public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
return imageBytes;
}
long srcSize = imageBytes.length;
double accuracy = getAccuracy(srcSize / 1024);
try {
while (imageBytes.length > desFileSize * 1024) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
Thumbnails.of(inputStream)
.scale(accuracy)
.outputQuality(accuracy)
.toOutputStream(outputStream);
imageBytes = outputStream.toByteArray();
}
System.out.println("图片原大小="+ (srcSize / 1024)+"kb | 压缩后大小={}kb" +( imageBytes.length / 1024) );
} catch (Exception e) {
System.out.println("【图片压缩】msg=图片压缩失败!"+e);
}
return imageBytes;
}
/**
* 自动调节精度(经验数值)
*
* @param size 源图片大小
* @return 图片压缩质量比
*/
private static double getAccuracy(long size) {
double accuracy;
if (size < 900) {
accuracy = 0.85;
} else if (size < 2047) {
accuracy = 0.6;
} else if (size < 3275) {
accuracy = 0.44;
} else {
accuracy = 0.4;
}
return accuracy;
}
private static BufferedImage toBufferedImage(Image img) {
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
return bimage;
}
/**
* 调整图片大小为指定宽度和高度
*
* @param imageBytes 源图片字节数组
* @param width 目标宽度
* @param height 目标高度
* @return 调整大小后的图片字节数组
*/
public static byte[] resizeImage(byte[] imageBytes, int width, int height) {
try {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Thumbnails.of(inputStream)
.size(width, height)
.outputFormat("jpg")
.toOutputStream(outputStream);
return outputStream.toByteArray();
} catch (Exception e) {
// log.error("【图片调整大小】msg=图片调整大小失败!", e);
return imageBytes; // 返回原始图片字节数组以防失败
}
}
}