海康NVR设备上传人脸图片到人脸库

  • 定义SDK接口:
  • 测试登录
  • 批量获取人脸库信息
  • 创建人脸库
  • 上传人脸图片到人脸库
    • 完整代码

海康开放平台——海康文档链接——海康开发包和文档下载链接

硬件:海康超脑NVR(全称Network Video Recorder,即网络视频录像机)、人脸摄像机。

环境:JDK_1.8 Windows 64位 jna.jar版本为3.0.9

<dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>3.0.9</version>
</dependency>

定义SDK接口:

自定义一个接口HCNetSDK,继承Library 或 StdCallLibrary。默认的是继承Library ,如果动态链接库里的函数是以stdcall方式输出的,那么就继承StdCallLibrary。接口内部需要一个公共静态常量:INSTANCE,通过这个常量,就可以获得这个接口的实例,从而使用接口的方法,也就是调用外部dll/so的函数。INSTANCE常量通过 Native.loadLibrary() API函数获得,(新版本的jna中,常量是通过Native.load()函数获取的)该函数有2个参数:

1)第一个参数是动态链接库dll/so的全路径名称(可以是绝对路径或者相对路径),本demo采用的是绝对路径。

2)第二个参数是自定义接口的Class类型。JNA通过这个Class类型,根据指定的.dll/.so文件,动态创建接口的实例。该实例由JNA通过反射自动生成。

// SDK接口说明,HCNetSDK.dll
public interface HCNetSDK extends StdCallLibrary {HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("E:\\DEMO_TEST\\JAVA_Demo\\JNA_TEST\\lib\\HCNetSDK.dll", HCNetSDK.class);// 动态库中结构体、接口描述public static class NET_DVR_USER_LOGIN_INFO extends Structure{public byte[] sDeviceAddress = new byte[NET_DVR_DEV_ADDRESS_MAX_LEN];public byte byUseTransport;public short wPort;public byte[] sUserName = new byte[NET_DVR_LOGIN_USERNAME_MAX_LEN];public byte[] sPassword = new byte[NET_DVR_LOGIN_PASSWD_MAX_LEN];public FLoginResultCallback cbLoginResult;public Pointer pUser;public boolean bUseAsynLogin;public byte byProxyType;   // 0:不使用代理,1:使用标准代理,2:使用EHome代理public byte byUseUTCTime;  // 0-不进行转换,默认,1-接口上输入输出全部使用UTC时间,SDK完成UTC时间与设备时区的转换,2-接口上输入输出全部使用平台本地时间,SDK完成平台本地时间与设备时区的转换public byte byLoginMode;   // 0-Private 1-ISAPI 2-自适应public byte byHttps;       // 0-不适用tls,1-使用tls 2-自适应public int iProxyID;    // 代理服务器序号,添加代理服务器信息时,相对应的服务器数组下表值public byte byVerifyMode;  // 认证方式,0-不认证,1-双向认证,2-单向认证;认证仅在使用TLS的时候生效;public byte[] byRes2 = new byte[119];// 结构体中重写getFieldOrder方法,FieldOrder顺序要和结构体中定义的顺序保持一致@Overrideprotected List getFieldOrder(){return  Arrays.asList("sDeviceAddress","byUseTransport","wPort","sUserName","sPassword",                                                               "cbLoginResult","pUser","bUseAsynLogin","byProxyType","byUseUTCTime","byLoginMode","byHttps","iProxyID","byVerifyMode","byRes2");} }// 常量(宏)定义public static final int NET_DVR_DEV_ADDRESS_MAX_LEN = 129;public static final int NET_DVR_LOGIN_USERNAME_MAX_LEN = 64;public static final int NET_DVR_LOGIN_PASSWD_MAX_LEN = 64;/*** API函数声明 ***/// 初始化SDK,调用其他SDK函数的前提boolean NET_DVR_Init();  // 启用日志文件写入接口boolean NET_DVR_SetLogToFile(int bLogEnable , String  strLogDir, boolean bAutoDel); // 返回最后操作的错误码int NET_DVR_GetLastError();  // 释放SDK资源,在程序结束之前调用boolean NET_DVR_Cleanup();// 登录接口int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo); // 用户注销boolean NET_DVR_Logout(int lUserID); // 回调函数申明public static interface FLoginResultCallback extends StdCallCallback{// 登录状态回调函数public int invoke(int lUserID,int dwResult,NET_DVR_DEVICEINFO_V30 lpDeviceinfo,Pointer pUser);
}

测试登录

package com.hik;
/*** @author test* @create 2021-02-07-15:53*/
public class jna_test {// 接口的实例,通过接口实例调用外部dll/so的函数static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE; // 用户登录返回句柄static int lUserID;  int iErr = 0;public static void main(String[] args) throws InterruptedException {jna_test test01 = new jna_test();// 初始化boolean initSuc = hCNetSDK.NET_DVR_Init();if (initSuc != true) {System.out.println("初始化失败");}// 打印SDK日志hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);// 用户登陆操作test01.Login_V40("192.168.1.64",(short)8000,"admin","test12345");/**实现SDK中其余功能模快*/Thread.sleep(5000);//用户注销,释放SDKtest01.Logout();    }/**** @param m_sDeviceIP 设备ip地址* @param wPort       端口号,设备网络SDK登录默认端口8000* @param m_sUsername 用户名* @param m_sPassword 密码*/public void Login_V40(String m_sDeviceIP,short wPort,String m_sUsername,String m_sPassword) {/* 注册 */// 设备登录信息HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();// 设备信息HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());m_strLoginInfo.wPort =wPort ;m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());// 是否异步登录:false- 否,true- 是m_strLoginInfo.bUseAsynLogin = false; // write()调用后数据才写入到内存中m_strLoginInfo.write();  lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);if (lUserID == -1) {System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());return;} else {System.out.println("登录成功!");// read()后,结构体中才有对应的数据 m_strDeviceInfo.read();  return;}}//设备注销 SDK释放public void Logout() {if (lUserID>=0){if (hCNetSDK.NET_DVR_Logout(lUserID) == false) {System.out.println("注销失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());}System.out.println("注销成功");hCNetSDK.NET_DVR_Cleanup();return;}else{System.out.println("设备未登录");hCNetSDK.NET_DVR_Cleanup();return;}}
}

批量获取人脸库信息

批量获取或设置人脸库信息:(命令:GET /ISAPI/Intelligent/FDLibPUT /ISAPI/Intelligent/FDLib);

  1. SDK初始化

      // 接口的实例,通过接口实例调用外部dll/so的函数static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;// step1:初始化boolean initSuc = hCNetSDK.NET_DVR_Init();if (initSuc != true) {System.out.println("初始化失败");}
    
  2. 打印SDK日志

      /*** 启用日志文件写入接口** @param bLogEnable 日志的等级(默认为0):0-表示关闭日志,1-表示只输出ERROR错误日志,2-输出ERROR错误信息和DEBUG调试信息,3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息* @param strLogDir  日志文件的路径,windows默认值为"C:\\SdkLog\\";linux默认值"/home/sdklog/"* @param bAutoDel   是否删除超出的文件数,默认值为TRUE* @return*/   // step2:打印SDK日志hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);
    
  3. 用户登陆操作

        // 登录接口int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
    
  4. 获取人脸库信息

        //命令 GET /ISAPI/Intelligent/FDLib//ISAPI协议命令透传boolean NET_DVR_STDXMLConfig(int lUserID, NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);
    

    批量获取人脸库信息方法

        public static final int ISAPI_DATA_LEN = 1024 * 1024;public static final int ISAPI_STATUS_LEN = 4 * 4096;public static final int BYTE_ARRAY_LEN = 1024;HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;/*** 批量获取人脸库信息** @param lUserID 登录返回的句柄*/public void getFaceLibInfo(int lUserID) {//获取人脸比对库能力集判断设备是否支持相关功能//  String url = "GET /ISAPI/Intelligent/FDLib/capabilities";//命令String url = "GET /ISAPI/Intelligent/FDLib";HCNetSDK.BYTE_ARRAY ptrUrl = new HCNetSDK.BYTE_ARRAY(BYTE_ARRAY_LEN);System.arraycopy(url.getBytes(), 0, ptrUrl.byValue, 0, url.length());// 数据写入到内存ptrUrl.write();//透传接口输入参数结构体HCNetSDK.NET_DVR_XML_CONFIG_INPUT netDvrXmlConfigInput = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT();//结构体大小netDvrXmlConfigInput.dwSize = netDvrXmlConfigInput.size();//请求信令,字符串格式netDvrXmlConfigInput.lpRequestUrl = ptrUrl.getPointer();//请求信令长度,字符串长度netDvrXmlConfigInput.dwRequestUrlLen = url.length();//输入参数缓冲区,XML/JSON格式netDvrXmlConfigInput.lpInBuffer = null;//ptrInBuffer.getPointer();//输入参数缓冲区大小netDvrXmlConfigInput.dwInBufferSize = 0;//ptrInBuffer.byValue.length;netDvrXmlConfigInput.write();HCNetSDK.BYTE_ARRAY ptrStatusByte = new HCNetSDK.BYTE_ARRAY(ISAPI_STATUS_LEN);HCNetSDK.BYTE_ARRAY ptrOutByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN);HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();struXMLOutput.dwSize = struXMLOutput.size();struXMLOutput.lpOutBuffer = ptrOutByte.getPointer();struXMLOutput.dwOutBufferSize = ptrOutByte.size();struXMLOutput.lpStatusBuffer = ptrStatusByte.getPointer();struXMLOutput.dwStatusSize = ptrStatusByte.size();struXMLOutput.write();//ISAPI协议命令透传if (!hCNetSDK.NET_DVR_STDXMLConfig(lUserID, netDvrXmlConfigInput, struXMLOutput)) {System.out.println("NET_DVR_STDXMLConfig失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());return;} else {struXMLOutput.read();ptrOutByte.read();ptrStatusByte.read();String strOutXML = new String(ptrOutByte.byValue).trim();System.out.println("获取设备能力集输出结果:" + strOutXML);String strStatus = new String(ptrStatusByte.byValue).trim();System.out.println("获取设备能力集返回状态:" + strStatus);}}
    
  5. 用户注销,释放SDK

        // 用户注销boolean NET_DVR_Logout(int lUserID);// 释放SDK资源,在程序结束之前调用boolean NET_DVR_Cleanup();
    

创建人脸库

创建人脸库:(命令:POST /ISAPI/Intelligent/FDLib);

  1. SDK初始化

      // 接口的实例,通过接口实例调用外部dll/so的函数static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;// step1:初始化boolean initSuc = hCNetSDK.NET_DVR_Init();if (initSuc != true) {System.out.println("初始化失败");}
    
  2. 打印SDK日志

      /*** 启用日志文件写入接口** @param bLogEnable 日志的等级(默认为0):0-表示关闭日志,1-表示只输出ERROR错误日志,2-输出ERROR错误信息和DEBUG调试信息,3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息* @param strLogDir  日志文件的路径,windows默认值为"C:\\SdkLog\\";linux默认值"/home/sdklog/"* @param bAutoDel   是否删除超出的文件数,默认值为TRUE* @return*/   // step2:打印SDK日志hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);
    
  3. 用户登陆操作

        // 登录接口int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
    
  4. 创建人脸库

        // 命令 POST /ISAPI/Intelligent/FDLib// ISAPI协议命令透传boolean NET_DVR_STDXMLConfig(int lUserID, NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);// 创建成功后// 使用dom4j解析xml,获取FDIDlpOutputParam.read();String xmlStr = lpOutputParam.lpOutBuffer.getString(0);// dom4j解析xmltry {Document document;document = DocumentHelper.parseText(xmlStr);Element FDLibInfoList = document.getRootElement();// 同时迭代当前节点下面的所有子节点Iterator<Element> iterator = FDLibInfoList.elementIterator();Element FDLibInfo = iterator.next();Iterator<Element> iterator2 = FDLibInfo.elementIterator();while (iterator2.hasNext()) {Element e = iterator2.next();if (e.getName().equals("FDID")) {String FDID = e.getText();System.out.println("FDID = " + FDID);}}} catch (DocumentException e1) {e1.printStackTrace();}
    

    创建人脸库方法

        public static final int ISAPI_DATA_LEN = 1024 * 1024;public static final int ISAPI_STATUS_LEN = 4 * 4096;public static final int BYTE_ARRAY_LEN = 1024;HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;/*** 创建人脸库** @param lUserID     登录返回的句柄* @param faceId      人脸库ID* @param faceLibName 人脸库名称(目前不能是中文)*/public void createFaceLib(int lUserID, String faceId, String faceLibName) {//创建人脸库String url = "POST /ISAPI/Intelligent/FDLib";HCNetSDK.BYTE_ARRAY ptrUrl = new HCNetSDK.BYTE_ARRAY(BYTE_ARRAY_LEN);System.arraycopy(url.getBytes(), 0, ptrUrl.byValue, 0, url.length());// 数据写入到内存ptrUrl.write();//透传接口输入参数结构体HCNetSDK.NET_DVR_XML_CONFIG_INPUT netDvrXmlConfigInput = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT();//结构体大小netDvrXmlConfigInput.dwSize = netDvrXmlConfigInput.size();//请求信令,字符串格式netDvrXmlConfigInput.lpRequestUrl = ptrUrl.getPointer();//请求信令长度,字符串长度netDvrXmlConfigInput.dwRequestUrlLen = url.length();// 人脸库名称String strInBuffer = new String("<CreateFDLibList><CreateFDLib><id>" + faceId + "</id><name>" + faceLibName+ "</name><thresholdValue>1</thresholdValue><autoUpdata>true</autoUpdata></CreateFDLib></CreateFDLibList>");HCNetSDK.BYTE_ARRAY ptrByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN);ptrByte.byValue = strInBuffer.getBytes();ptrByte.write();netDvrXmlConfigInput.lpInBuffer = ptrByte.getPointer();netDvrXmlConfigInput.dwInBufferSize = strInBuffer.length();netDvrXmlConfigInput.write();HCNetSDK.BYTE_ARRAY ptrStatusByte = new HCNetSDK.BYTE_ARRAY(ISAPI_STATUS_LEN);HCNetSDK.BYTE_ARRAY ptrOutByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN);HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();struXMLOutput.dwSize = struXMLOutput.size();struXMLOutput.lpOutBuffer = ptrOutByte.getPointer();struXMLOutput.dwOutBufferSize = ptrOutByte.size();struXMLOutput.lpStatusBuffer = ptrStatusByte.getPointer();struXMLOutput.dwStatusSize = ptrStatusByte.size();struXMLOutput.write();//ISAPI协议命令透传if (!hCNetSDK.NET_DVR_STDXMLConfig(lUserID, netDvrXmlConfigInput, struXMLOutput)) {System.out.println("NET_DVR_STDXMLConfig失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());return;} else {struXMLOutput.read();ptrOutByte.read();ptrStatusByte.read();String strOutXML = new String(ptrOutByte.byValue).trim();System.out.println("获取设备能力集输出结果:" + strOutXML);String xmlStr = struXMLOutput.lpOutBuffer.getString(0);// dom4j解析xmltry {Document document;document = DocumentHelper.parseText(xmlStr);Element FDLibInfoList = document.getRootElement();// 同时迭代当前节点下面的所有子节点Iterator<Element> iterator = FDLibInfoList.elementIterator();Element FDLibInfo = iterator.next();Iterator<Element> iterator2 = FDLibInfo.elementIterator();while (iterator2.hasNext()) {Element e = iterator2.next();if (e.getName().equals("FDID")) {String FDID = e.getText();System.out.println("FDID = " + FDID);}}} catch (DocumentException e1) {e1.printStackTrace();}}}
    
  5. 用户注销,释放SDK

        // 用户注销boolean NET_DVR_Logout(int lUserID);// 释放SDK资源,在程序结束之前调用boolean NET_DVR_Cleanup();
    

上传人脸图片到人脸库

人脸对比文档链接

  1. 初始化SDK NET_DVR_Init
  2. 用户注册 NET_DVR_Login_V40
  3. 创建人脸库 NET_DVR_STDXMLConfig 命令: POST /ISAPI/Intelligent/FDLib
  4. 建立人脸数据上传的长链接 NET_DVR_UploadFile_V40(命令:IMPORT_DATA_TO_FACELIB)
  5. 上传人脸数据(人脸图片+图片附加信息)到人脸库 NET_DVR_UploadSend
  6. 获取上传状态和进度 NET_DVR_GetUploadState
  7. 获取结果信息(图片ID) NET_DVR_GetUploadResult
  8. 上传结束,断开链接,释放资源 NET_DVR_UploadClose
  9. 注销用户 NET_DVR_Logout
  10. 释放SDK资源 NET_DVR_Cleanup
  • 上传接口调用流程

    (1) 调用NET_DVR_UploadFile_V40(命令:IMPORT_DATA_TO_FACELIB)开始上传数据。上传条件里面NET_DVR_FACELIB_COND.byConcurrent赋值为0时不开启并发处理,设备会自动对上传的图片进行建模,如果批量上传大量图片,可以赋值为1开启并发处理,提高速度,但是上传之后需要自己建模。

    (2) 调用NET_DVR_UploadSend发送一张人脸图片数据和附加信息。

    (3) 上传过程中循环调用NET_DVR_GetUploadState获取上传状态和进度。

    (4) 上传成功之后调用NET_DVR_GetUploadResult获取结果信息(图片ID等)。

    (5) 重复步骤2、3、4,顺序上传其他人脸数据。

    (6) 调用NET_DVR_UploadClose停止上传,释放资源。

完整代码

HCNetSDK.java

import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;import java.util.Arrays;
import java.util.List;// SDK接口说明,HCNetSDK.dll
public interface HCNetSDK extends StdCallLibrary {HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("C:\\Users\\ZhangWanPeng\\Desktop\\HCNetSDK.dll", HCNetSDK.class);// 常量(宏)定义public static final int NAME_LEN = 32;    //用户名长度public static final int MACADDR_LEN = 6;      //mac地址长度public static final int NET_DVR_DEV_ADDRESS_MAX_LEN = 129;public static final int NET_DVR_LOGIN_USERNAME_MAX_LEN = 64;public static final int NET_DVR_LOGIN_PASSWD_MAX_LEN = 64;public static final int SERIALNO_LEN = 48;   //序列号长度public static final int NET_SDK_CONFIG_STATUS_SUCCESS = 1000;public static final int NET_SDK_CONFIG_STATUS_NEEDWAIT = 1001;public static final int NET_SDK_CONFIG_STATUS_FINISH = 1002;public static final int NET_SDK_CONFIG_STATUS_FAILED = 1003;public static final int NET_SDK_CONFIG_STATUS_EXCEPTION = 1004;public static final int IMPORT_DATA_TO_FACELIB = 39; //导入人脸数据(人脸图片+图片附加信息)到人脸库/*** 人脸库ID最大长度*/public static final int NET_SDK_MAX_FDID_LEN = 256;// 文件上传URL最大长度public static final int MAX_UPLOADFILE_URL_LEN = 240;// 动态库中结构体、接口描述public static class NET_DVR_USER_LOGIN_INFO extends Structure {public byte[] sDeviceAddress = new byte[NET_DVR_DEV_ADDRESS_MAX_LEN];public byte byUseTransport;public short wPort;public byte[] sUserName = new byte[NET_DVR_LOGIN_USERNAME_MAX_LEN];public byte[] sPassword = new byte[NET_DVR_LOGIN_PASSWD_MAX_LEN];public FLoginResultCallback cbLoginResult;public Pointer pUser;public boolean bUseAsynLogin;public byte byProxyType;   // 0:不使用代理,1:使用标准代理,2:使用EHome代理public byte byUseUTCTime;  // 0-不进行转换,默认,1-接口上输入输出全部使用UTC时间,SDK完成UTC时间与设备时区的转换,2-接口上输入输出全部使用平台本地时间,SDK完成平台本地时间与设备时区的转换public byte byLoginMode;   // 0-Private 1-ISAPI 2-自适应public byte byHttps;       // 0-不适用tls,1-使用tls 2-自适应public int iProxyID;    // 代理服务器序号,添加代理服务器信息时,相对应的服务器数组下表值public byte byVerifyMode;  // 认证方式,0-不认证,1-双向认证,2-单向认证;认证仅在使用TLS的时候生效;public byte[] byRes2 = new byte[119];// 结构体中重写getFieldOrder方法,FieldOrder顺序要和结构体中定义的顺序保持一致@Overrideprotected List getFieldOrder() {return Arrays.asList("sDeviceAddress", "byUseTransport", "wPort", "sUserName", "sPassword", "cbLoginResult", "pUser", "bUseAsynLogin", "byProxyType", "byUseUTCTime","byLoginMode", "byHttps", "iProxyID", "byVerifyMode", "byRes2");}}//NET_DVR_Login_V30()参数结构public static class NET_DVR_DEVICEINFO_V30 extends Structure {public byte[] sSerialNumber = new byte[SERIALNO_LEN];  //序列号public byte byAlarmInPortNum;    //报警输入个数public byte byAlarmOutPortNum;   //报警输出个数public byte byDiskNum;           //硬盘个数public byte byDVRType;         //设备类型, 1:DVR 2:ATM DVR 3:DVS ......public byte byChanNum;         //模拟通道个数public byte byStartChan;      //起始通道号,例如DVS-1,DVR - 1public byte byAudioChanNum;    //语音通道数public byte byIPChanNum;     //最大数字通道个数,低位public byte byZeroChanNum;    //零通道编码个数 //2010-01-16public byte byMainProto;      //主码流传输协议类型 0-private, 1-rtsp,2-同时支持private和rtsppublic byte bySubProto;        //子码流传输协议类型0-private, 1-rtsp,2-同时支持private和rtsppublic byte bySupport;        //能力,位与结果为0表示不支持,1表示支持,public byte bySupport1;        // 能力集扩充,位与结果为0表示不支持,1表示支持public byte bySupport2; /*能力*/public short wDevType;              //设备型号public byte bySupport3; //能力集扩展public byte byMultiStreamProto;//是否支持多码流,按位表示,0-不支持,1-支持,bit1-码流3,bit2-码流4,bit7-主码流,bit-8子码流public byte byStartDChan;        //起始数字通道号,0表示无效public byte byStartDTalkChan;    //起始数字对讲通道号,区别于模拟对讲通道号,0表示无效public byte byHighDChanNum;        //数字通道个数,高位public byte bySupport4;        //能力集扩展public byte byLanguageType;// 支持语种能力,按位表示,每一位0-不支持,1-支持//  byLanguageType 等于0 表示 老设备//  byLanguageType & 0x1表示支持中文//  byLanguageType & 0x2表示支持英文public byte byVoiceInChanNum;   //音频输入通道数public byte byStartVoiceInChanNo; //音频输入起始通道号 0表示无效public byte byRes3;        //保留public byte byMirrorChanNum;    //镜像通道个数,<录播主机中用于表示导播通道>public short wStartMirrorChanNo;  //起始镜像通道号public byte byRes2;        //保留}//NET_DVR_Login_V40()参数public static class NET_DVR_DEVICEINFO_V40 extends Structure {public NET_DVR_DEVICEINFO_V30 struDeviceV30 = new NET_DVR_DEVICEINFO_V30();public byte bySupportLock;public byte byRetryLoginTime;public byte byPasswordLevel;public byte byProxyType;public int dwSurplusLockTime;public byte byCharEncodeType;//字符编码类型:0- 无字符编码信息(老设备),1- GB2312(简体中文),2- GBK,3- BIG5(繁体中文),4- Shift_JIS(日文),5- EUC-KR(韩文),6- UTF-8,7- ISO8859-1,8- ISO8859-2,9- ISO8859-3,…,依次类推,21- ISO8859-15(西欧)public byte bySupportDev5; //支持v50版本的设备参数获取,设备名称和设备类型名称长度扩展为64字节public byte byLoginMode; //登录模式 0-Private登录 1-ISAPI登录public byte[] byRes2 = new byte[253];}//预览参数结构体public static class NET_DVR_PREVIEWINFO extends Structure {public int lChannel;//通道号public int dwStreamType;    // 码流类型,0-主码流,1-子码流,2-码流3,3-码流4, 4-码流5,5-码流6,7-码流7,8-码流8,9-码流9,10-码流10public int dwLinkMode;// 0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-RTP/RTSP,5-RSTP/HTTP ,6- HRUDP(可靠传输) ,7-RTSP/HTTPSpublic W32API.HWND hPlayWnd;//播放窗口的句柄,为NULL表示不播放图象public int bBlocked;  //0-非阻塞取流, 1-阻塞取流, 如果阻塞SDK内部connect失败将会有5s的超时才能够返回,不适合于轮询取流操作.public int bPassbackRecord; //0-不启用录像回传,1启用录像回传public byte byPreviewMode;//预览模式,0-正常预览,1-延迟预览public byte[] byStreamID = new byte[32];//流ID,lChannel为0xffffffff时启用此参数public byte byProtoType; //应用层取流协议,0-私有协议,1-RTSP协议public byte byRes1;public byte byVideoCodingType; //码流数据编解码类型 0-通用编码数据 1-热成像探测器产生的原始数据(温度数据的加密信息,通过去加密运算,将原始数据算出真实的温度值)public int dwDisplayBufNum; //播放库播放缓冲区最大缓冲帧数,范围1-50,置0时默认为1public byte byNPQMode;    //NPQ是直连模式,还是过流媒体 0-直连 1-过流媒体public byte[] byRes = new byte[215];}//上传文件public static class NET_DVR_UploadFile_V40 extends Structure {public int lUserID;public int dwUploadType;public byte[] lpInBuffer;}public static class BYTE_ARRAY extends Structure {public byte[] byValue;public BYTE_ARRAY(int iLen) {byValue = new byte[iLen];}}//JSON数据配置结构体public static class NET_DVR_JSON_DATA_CFG extends Structure {public int dwSize;                        //结构体大小public Pointer lpJsonData;                //JSON报文public int dwJsonDataSize;                //JSON报文大小public Pointer lpPicData;                //图片内容public int dwPicDataSize;                //图片内容大小public int lpInfraredFacePicBuffer;        //红外人脸图片数据缓存public Pointer dwInfraredFacePicSize;    //红外人脸图片数据大小,等于0时,代表无人脸图片数据(当JSON报文为当ResponseStatus(JSON)报文时,该字段无意义;当Inbound Data(JSON)报文中没有infraredFaceURL时,该字段需要带上二进制图片内容)public byte[] byRes = new byte[248];}//报警设备信息public static class NET_DVR_ALARMER extends Structure {public byte byUserIDValid;                 /* userid是否有效 0-无效,1-有效 */public byte bySerialValid;                 /* 序列号是否有效 0-无效,1-有效 */public byte byVersionValid;                /* 版本号是否有效 0-无效,1-有效 */public byte byDeviceNameValid;             /* 设备名字是否有效 0-无效,1-有效 */public byte byMacAddrValid;                /* MAC地址是否有效 0-无效,1-有效 */public byte byLinkPortValid;               /* login端口是否有效 0-无效,1-有效 */public byte byDeviceIPValid;               /* 设备IP是否有效 0-无效,1-有效 */public byte bySocketIPValid;               /* socket ip是否有效 0-无效,1-有效 */public int lUserID;                       /* NET_DVR_Login()返回值, 布防时有效 */public byte[] sSerialNumber = new byte[SERIALNO_LEN];    /* 序列号 */public int dwDeviceVersion;                /* 版本信息 高16位表示主版本,低16位表示次版本*/public byte[] sDeviceName = new byte[NAME_LEN];            /* 设备名字 */public byte[] byMacAddr = new byte[MACADDR_LEN];        /* MAC地址 */public short wLinkPort;                     /* link port */public byte[] sDeviceIP = new byte[128];                /* IP地址 */public byte[] sSocketIP = new byte[128];                /* 报警主动上传时的socket IP地址 */public byte byIpProtocol;                  /* Ip协议 0-IPV4, 1-IPV6 */public byte[] byRes2 = new byte[11];}/*** 导入人脸数据(人脸图片+图片附件信息)到人脸库的条件参数结构体*/public static class NET_DVR_FACELIB_COND extends Structure {public int dwSize;  //结构体大小public byte[] szFDID = new byte[256]; //人脸库ID(设备自动生成的FDID或者是自定义的customFaceLibID),唯一标识public byte byConcurrent; //设备并发处理:0- 不开启(设备自动会建模),1- 开始(设备不会自动进行建模)public byte byCover;  //是否覆盖式导入(人脸库存储满的情况下强制覆盖导入时间最久的图片数据):0- 否,1- 是public byte byCustomFaceLibID; //人脸库ID是否是自定义:0- 不是,1- 是public byte byRes1; //保留,置为0public byte[] byIdentityKey = new byte[64]; //交互操作口令public byte[] byRes = new byte[60];  //保留,置为0}//数据发送输入参数结构体public static class NET_DVR_SEND_PARAM_IN extends Structure {public Pointer pSendData;             //发送的缓冲区,PicURL == 1 的时候,内存中存储的是 URL 字符串,byUploadModeling == 1 的时候,内存中存储的是 建模base64加密数据public int dwSendDataLen;         //发送数据长度,PicURL == 1 的时候,表示的 URL 字符串的长度,byUploadModeling == 1 的时候,表示为建模数据base64后的加密长度public NET_DVR_TIME_V30 struTime = new NET_DVR_TIME_V30();   //图片时间public byte byPicType;              //图片格式,1-jpg,2-bmp,3-png,4-SWF,5-GIFpublic byte byPicURL;               //图片数据采用URL方式 0-二进制图片数据,1-图片数据走URL方式/*是否上传建模数据;0- 二进制图片数据方式(pSendData指向二进制图片数据, dwPicDataLen为图片二进制数据长度),1- 直接上传建模数据(pSendData指向建模base64加密数据, dwPicDataLen为建模数据base64后的加密长度)。注:建模数据采用base64加密方式,选择为建模数据上传后,byPicURL 无需。当”/ISAPI/Intelligent/channels/<ID>/faceContrast/capabilities”能力中返回isSupportUploadModeling能力节点时,支持上传建模数据. */public byte byUploadModeling;public byte byRes1;public int dwPicMangeNo;           //图片管理号public byte[] sPicName = new byte[NAME_LEN];     //图片名称public int dwPicDisplayTime;       //图片播放时长,单位秒public Pointer pSendAppendData;       //发送图片的附加信息缓冲区,对应FaceAppendData 的XML描述;public int dwSendAppendDataLen;    //发送图片的附加信息数据长度  FaceAppendData  XML的长度;public byte[] byRes = new byte[192];}/*** 文件上传结果信息结构体*/public static class NET_DVR_UPLOAD_FILE_RET extends Structure {public byte[] sUrl = new byte[MAX_UPLOADFILE_URL_LEN];  //文件上传返回的URL或者IDpublic byte[] byRes = new byte[260];  //保留}public static class NET_DVR_TIME_V30 extends Structure {public short wYear;public byte byMonth;public byte byDay;public byte byHour;public byte byMinute;public byte bySecond;public byte byRes;public short wMilliSec;public byte[] byRes1 = new byte[2];}/*** 透传接口输入参数结构体*/public static class NET_DVR_XML_CONFIG_INPUT extends Structure {public int dwSize; //结构体大小public Pointer lpRequestUrl; //请求信令,字符串格式public int dwRequestUrlLen; //请求信令长度,字符串长度public Pointer lpInBuffer; //输入参数缓冲区,XML/JSON格式public int dwInBufferSize; //输入参数缓冲区大小public int dwRecvTimeOut; //报文分段个数:0- 无效;  其他- lpInBuffer传入NET_DVR_MIME_UNIT结构体指针,该值即代表结构体个数public byte[] byRes = new byte[32]; //保留,置为0}/*** 透传接口输出参数结构体*/public static class NET_DVR_XML_CONFIG_OUTPUT extends Structure {public int dwSize; //结构体大小public Pointer lpOutBuffer; //输出参数缓冲区,XML/JSON格式,请求信令为“GET”类型时应用层需要事先分配足够大的内存public int dwOutBufferSize; //输出参数缓冲区大小(内存大小)public int dwReturnedXMLSize; //实际输出的XML/JSON内容大小public Pointer lpStatusBuffer; //返回的状态参数(XML/JSON格式:ResponseStatus),获取命令成功时不会赋值,如果不需要,可以置NULLpublic int dwStatusSize; //状态缓冲区大小(内存大小)public byte[] byRes = new byte[32]; //保留,置为0}public static interface FRemoteConfigCallBack extends StdCallCallback {public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData);}/*** API函数声明 ***/// 初始化SDK,调用其他SDK函数的前提boolean NET_DVR_Init();/*** 启用日志文件写入接口** @param bLogEnable 日志的等级(默认为0):0-表示关闭日志,1-表示只输出ERROR错误日志,2-输出ERROR错误信息和DEBUG调试信息,3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息* @param strLogDir  日志文件的路径,windows默认值为"C:\\SdkLog\\";linux默认值"/home/sdklog/"* @param bAutoDel   是否删除超出的文件数,默认值为TRUE* @return*/boolean NET_DVR_SetLogToFile(int bLogEnable, String strLogDir, boolean bAutoDel);// 返回最后操作的错误码int NET_DVR_GetLastError();// 释放SDK资源,在程序结束之前调用boolean NET_DVR_Cleanup();// 登录接口int NET_DVR_Login_V40(NET_DVR_USER_LOGIN_INFO pLoginInfo, NET_DVR_DEVICEINFO_V40 lpDeviceInfo);// 用户注销boolean NET_DVR_Logout(int lUserID);// 回调函数申明public static interface FLoginResultCallback extends StdCallCallback {// 登录状态回调函数public int invoke(int lUserID, int dwResult, NET_DVR_DEVICEINFO_V30 lpDeviceinfo, Pointer pUser);}public static interface FRealDataCallback_V30 extends Callback {public void invoke(int lRealHandle, int dwDataType,ByteByReference pBuffer, int dwBufSize, Pointer pUser);}public static interface FMSGCallBack_V31 extends StdCallCallback {public boolean invoke(int lCommand, NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser);}// 设置网络连接超时时间和连接尝试次数。boolean NET_DVR_SetConnectTime(int dwWaitTime, int dwTryTimes);// NET_DVR_SetReconnectboolean NET_DVR_SetReconnect(int dwInterval, int bEnableRecon);/*** 上传文件** @param lUserID         NET_DVR_Login_V40等登录接口的返回值* @param dwUploadType    上传文件类型* @param lpInBuffer      输入参数* @param dwInBufferSize  输入缓冲区大小* @param sFileName       上传文件的路径(包括文件名)* @param lpOutBuffer     输出参数* @param dwOutBufferSize 输出缓冲区大小* @return*/int NET_DVR_UploadFile_V40(int lUserID, int dwUploadType, Pointer lpInBuffer, int dwInBufferSize, String sFileName, Pointer lpOutBuffer, int dwOutBufferSize);/*** 发送数据** @param lUploadHandle    文件上传句柄,NET_DVR_UploadFile_V40的返回值* @param pstruSendParamIN 上传的数据内容* @param lpOutBuffer      输出参数,保留,置为NULL* @return*/int NET_DVR_UploadSend(int lUploadHandle, Pointer pstruSendParamIN, Void lpOutBuffer);//启动远程配置int NET_DVR_StartRemoteConfig(int lUserID, int dwCommand, Pointer lpInBuffer, int dwInBufferLen, FRemoteConfigCallBack cbStateCallBack, Pointer pUserData);int NET_DVR_SendWithRecvRemoteConfig(int lHandle, Pointer lpInBuff, int dwInBuffSize, Pointer lpOutBuff, int dwOutBuffSize, IntByReference dwOutDataLen);boolean NET_DVR_StopRemoteConfig(int lHandle);//获取设备能力集boolean NET_DVR_GetDeviceAbility(int lUserID, int dwAbilityType, Pointer pInBuf, int dwInLength, Pointer pOutBuf, int dwOutLength);boolean NET_DVR_SetDVRMessageCallBack_V31(FMSGCallBack_V31 fMessageCallBack, Pointer pUser);/*** 获取文件上传的进度和状态** @param lUploadHandle 文件上传的句柄,NET_DVR_UploadFile_V40的返回值* @param pProgress     返回的进度值,0~100* @return*/int NET_DVR_GetUploadState(int lUploadHandle, Pointer pProgress);/*** 获取当前上传的结果信息** @param lUploadHandle   文件上传的句柄,NET_DVR_UploadFile_V40的返回值* @param lpOutBuffer     结果信息缓冲区* @param dwOutBufferSize 缓冲区大小* @return*/boolean NET_DVR_GetUploadResult(int lUploadHandle, Pointer lpOutBuffer, int dwOutBufferSize);//停止文件上传boolean NET_DVR_UploadClose(int lUploadHandle);//ISAPI协议命令透传boolean NET_DVR_STDXMLConfig(int lUserID, NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);}

UploadFaceUtil.java

import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;/*** @author ZWP* @date 2022/1/28 14:00*/
public class UploadFaceUtil {HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;/*** SDK登录** @param m_sDeviceIP 设备ip地址* @param wPort       端口号,设备网络SDK登录默认端口8000* @param m_sUsername 用户名* @param m_sPassword 密码* @return*/public int login(String m_sDeviceIP, short wPort, String m_sUsername, String m_sPassword) {// 初始化boolean initSuc = hCNetSDK.NET_DVR_Init();if (!initSuc) {System.out.println("初始化失败");return -1;}// 打印SDK日志hCNetSDK.NET_DVR_SetLogToFile(3, ".\\SDKLog\\", false);/* 注册 */// 设备登录信息HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());m_strLoginInfo.wPort = wPort;m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());// 是否异步登录:false- 否,true- 是m_strLoginInfo.bUseAsynLogin = false;// write()调用后数据才写入到内存中m_strLoginInfo.write();// 设备信息HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);if (lUserID == -1) {System.out.println("登录失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());} else {System.out.println("登录成功!");// read()后,结构体中才有对应的数据m_strDeviceInfo.read();}return lUserID;}/*** 设备注销 SDK释放*/public void logout(int lUserID) {if (lUserID >= 0) {// 注销if (!hCNetSDK.NET_DVR_Logout(lUserID)) {System.out.println("注销失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());}System.out.println("注销成功");// 释放SDK资源hCNetSDK.NET_DVR_Cleanup();} else {System.out.println("设备未登录");hCNetSDK.NET_DVR_Cleanup();}}/*** 建立图片上传连接** @param lUserID 用户句柄(登录的返回值)* @param strFDID 人脸库ID(设备自动生成的FDID或者是自定义的customFaceLibID),唯一标识*/public int faceupload(int lUserID, String strFDID) {HCNetSDK.NET_DVR_FACELIB_COND struInput = new HCNetSDK.NET_DVR_FACELIB_COND();//结构体大小struInput.dwSize = struInput.size();//设备并发处理:0- 不开启(设备自动会建模),1- 开始(设备不会自动进行建模)struInput.byConcurrent = 0;//人脸库ID是否是自定义:0- 不是,1- 是struInput.byCustomFaceLibID = 0;//是否覆盖式导入(人脸库存储满的情况下强制覆盖导入时间最久的图片数据):0- 否,1- 是struInput.byCover = 1;struInput.szFDID = new byte[HCNetSDK.NET_SDK_MAX_FDID_LEN]; //人脸库ID最大长度 256//将指定源数组中的数组从指定位置复制到目标数组的指定位置。System.arraycopy(strFDID.getBytes(), 0, struInput.szFDID, 0, strFDID.getBytes().length);//数据写入到内存中struInput.write();// 获取Pointer对象Pointer inputPointer = struInput.getPointer();// 上传人脸图片int uploadFileV40 = hCNetSDK.NET_DVR_UploadFile_V40(lUserID, HCNetSDK.IMPORT_DATA_TO_FACELIB, inputPointer, struInput.size(), null, null, 0);if (uploadFileV40 == -1) {System.out.println("上传失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());} else {System.out.println("上传成功!");}return uploadFileV40;}/*** 上传图片** @param lUploadHandle 文件上传的句柄* @param picPath       图片路径* @param dataXMLPath   XML文件路径*/public void uploadSend(int lUploadHandle, String picPath, String dataXMLPath) {//图片文件FileInputStream picfile = null;//XML文件(附加消息)FileInputStream xmlfile = null;int picdataLength = 0;int xmldataLength = 0;try {// 创建文件picfile = new FileInputStream(new File(System.getProperty("user.dir") + picPath));xmlfile = new FileInputStream(new File(System.getProperty("user.dir") + dataXMLPath));// 获取文件的字节数picdataLength = picfile.available();xmldataLength = xmlfile.available();} catch (IOException e) {e.printStackTrace();}if (picdataLength < 0 || xmldataLength < 0) {System.out.println("上传图片大小/xml文件大小 < 0");return;}HCNetSDK.BYTE_ARRAY ptrpicByte = new HCNetSDK.BYTE_ARRAY(picdataLength);HCNetSDK.BYTE_ARRAY ptrxmlByte = new HCNetSDK.BYTE_ARRAY(xmldataLength);try {// 从内存中读取数据到byte数组picfile.read(ptrpicByte.byValue);xmlfile.read(ptrxmlByte.byValue);} catch (IOException e) {e.printStackTrace();}//数据写入到内存中ptrpicByte.write();ptrxmlByte.write();HCNetSDK.NET_DVR_SEND_PARAM_IN netDvrSendParamIn = new HCNetSDK.NET_DVR_SEND_PARAM_IN();//图片格式:1- jpg,2- bmp,3- png,4- SWF,5- GIFnetDvrSendParamIn.byPicType = 1;// 图片管理号,人脸库不支持,设为0netDvrSendParamIn.dwPicMangeNo = 0;// 图片播放时长,单位:秒,人脸库不支持,设为0netDvrSendParamIn.dwPicDisplayTime = 0;netDvrSendParamIn.byPicURL = 0;// 发送的缓冲区,PicURL == 1 的时候,内存中存储的是 URL 字符串,byUploadModeling == 1 的时候,内存中存储的是 建模base64加密数据netDvrSendParamIn.pSendData = ptrpicByte.getPointer();// 发送数据长度,PicURL == 1 的时候,表示的 URL 字符串的长度,byUploadModeling == 1 的时候,表示为建模数据base64后的加密长度netDvrSendParamIn.dwSendDataLen = picdataLength;// 发送图片的附加信息缓冲区,对应FaceAppendData 的XML描述;netDvrSendParamIn.pSendAppendData = ptrxmlByte.getPointer();// 发送图片的附加信息数据长度  FaceAppendData XML的长度;netDvrSendParamIn.dwSendAppendDataLen = xmldataLength;//数据写入到内存中netDvrSendParamIn.write();// 发送数据int dvrUploadSend = hCNetSDK.NET_DVR_UploadSend(lUploadHandle, netDvrSendParamIn.getPointer(), null);if (dvrUploadSend == -1) {System.out.println("发送数据失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());return;} else {System.out.println("发送数据成功!");}// 关闭流try {picfile.close();xmlfile.close();} catch (IOException e) {e.printStackTrace();}}/*** 获取上传状态和进度** @param lUploadHandle 文件上传的句柄*/public int getUploadState(int lUploadHandle) throws InterruptedException {Thread.sleep(500);// 原生整型引用IntByReference pInt = new IntByReference(0);int netDvrGetUploadState = hCNetSDK.NET_DVR_GetUploadState(lUploadHandle, pInt.getPointer());switch (netDvrGetUploadState) {case -1:System.out.println("获取文件上传的进度和状态失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());break;case 1:System.out.println("progress = " + pInt.getValue());System.out.println("获取文件上传的进度和状态成功!");break;case 2:System.out.println("正在上传!!!!  progress = " + pInt.getValue());break;default:System.out.println("获取文件上传的进度和状态失败!,接口返回值为 = " + netDvrGetUploadState);System.out.println("获取文件上传的进度和状态失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());break;}return netDvrGetUploadState;}/*** 获取结果信息(图片ID等)** @param lUploadHandle 文件上传的句柄*/public String getUploadResult(int lUploadHandle) {// 图片IDString picID = null;// 文件上传结果信息结构体HCNetSDK.NET_DVR_UPLOAD_FILE_RET netDvrUploadFileRet = new HCNetSDK.NET_DVR_UPLOAD_FILE_RET();// 数据写入到内存中netDvrUploadFileRet.write();// 获取结果信息if (!hCNetSDK.NET_DVR_GetUploadResult(lUploadHandle, netDvrUploadFileRet.getPointer(), netDvrUploadFileRet.size())) {System.out.println("获取结果信息失败!,错误码为" + hCNetSDK.NET_DVR_GetLastError());} else {// 从内存中读取数据netDvrUploadFileRet.read();// 文件上传返回的URL或者IDpicID = String.valueOf(netDvrUploadFileRet.sUrl).trim();System.out.println("图片上传成功 PicID:" + picID);}return picID;}
}

UploadFace.java

/*** @author ZWP* @date 2022/1/28 13:58*/
public class UploadFace {static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;static int lUserID = -1;//用户句柄static int m_lUploadHandle = -1;//文件上传句柄static int m_UploadStatus = -1;//上传进度值public static void main(String[] args) throws InterruptedException {UploadFaceUtil uploadFaceUtil = new UploadFaceUtil();// 用户登陆操作==初始化==打印SDK日志lUserID = uploadFaceUtil.login("192.168.7.43", (short) 8000, "admin", "123456");// step1:创建人脸库// step2:建立图片上传的长连接m_lUploadHandle = uploadFaceUtil.faceupload(lUserID, "06CD85AED2FE4F82B7FD7C878EDD91BF");if (m_lUploadHandle == -1) {return;}// step3:上传图片uploadFaceUtil.uploadSend(m_lUploadHandle, "\\pic\\face.jpg", "\\pic\\data.xml");// step4:获取上传状态和进度m_UploadStatus = uploadFaceUtil.getUploadState(m_lUploadHandle);if (m_UploadStatus == 1) {// step5:上传成功之后调用NET_DVR_GetUploadResult获取结果信息(图片ID等)。String uploadResult = uploadFaceUtil.getUploadResult(m_lUploadHandle);System.out.println("PicID:" + uploadResult);}if (m_UploadStatus >= 3 || m_UploadStatus == -1) {System.out.println("m_UploadStatus = " + m_UploadStatus);m_lUploadHandle = -1;}// step6:停止文件上传hCNetSDK.NET_DVR_UploadClose(m_lUploadHandle);// 线程睡眠5秒钟Thread.sleep(5000);// step7:用户注销,释放SDKuploadFaceUtil.logout(lUserID);}
}

data.xml

<FaceAppendData><bornTime>2022-01-28</bornTime><name>张万鹏</name><sex>male</sex><province>11</province><city>01</city><certificateType>officerID</certificateType><certificateNumber>1123123123</certificateNumber><PersonInfoExtendList><PersonInfoExtend><id>1</id><enable>false</enable><name>test1</name><value>test2</value></PersonInfoExtend></PersonInfoExtendList>
</FaceAppendData>

海康NVR设备上传人脸图片到人脸库相关推荐

  1. 使用GB28181从海康NVR设备上获取实时视频

    本人现在已经不做音视频方向了,所以大家的一些疑问可能无法解答,相关资料基本都在下载链接中,希望可以帮助到大家. 正文: 最近在调研使用GB28181协议获取海康NVR设备上的实时视音频数据,真的是搞了 ...

  2. 海康NVR设备RTSP协议转RTMP协议

    Title:海康NVR设备RTSP协议转RTMP协议 Date: 2017-10-17 Author: kagula 环境: [1]海康NVR设备  型号为DS-7808N-E2/8P [2]Cent ...

  3. 海康NVR中INVITE请求一直返回 400 Bad Request

    最近对接海康NVR设备一直返回 400 Bad Request 如下: 首先我查询了via/from/to/subject/contact确认都没问题,然后测试总是出现下问题 INVITE sip:4 ...

  4. 大华sdk(java)上传人脸图片到人脸库,订阅人脸识别对比

    上传人脸图片到人脸库 controller: @RestController @RequestMapping("/facePicture") public class FacePi ...

  5. LiveGBS国标流媒体平台-海康NVR摄像机自带物联网卡摄像头注册GB/T28181国标平台看不到设备的时候如何抓包及排查

    GB/T28181国标流媒体平台海康大华宇视华为等硬件NVR摄像机注册到LiveGBS国标平台看不到设备的时候如何抓包及排查 1.设备注册后查看不到 1.1.是否是自带物联网卡的摄像头 1.2.关闭萤 ...

  6. p6s与onvif_[海康NVR]关于NVR与ONVIF协议的问题

    1. 如果使用RTSP连接我司的设备网络串流的格式是什么? 答:使用第3方的播放器通过RTSP连接我司设备的URL格式可去公司网站下载 如果是通过公网需要将RTSP端口开放(默认是554),这个端口在 ...

  7. 国标服务器GBServerPlatform对接海康NVR的操作说明

    这一篇文章介绍QuickGBLink开发的国标服务器如何对接海康NVR(网络硬盘录像机),主要讲解相关的操作步骤. (GBT28181平台软件下载地址:https://github.com/Quick ...

  8. 基于ZYNQ的网页上传BMP图片至HDMI端口输出实例

    目录 Change Log 0 前言 0.1 系统实现 0.2 源码下载 0.3 项目信息 1 ZYNQ开发板HDMI输出BMP图片功能:FPGA相关 1.1 系统框图 1.2 RTL图 1.3 Bl ...

  9. 海康NVR回放导出工具

    海康NVR的录像回放导出功能,迅速导出回放录像,10分钟1080p的录像导出约4秒钟 支持 7916等支持ocx在线播放的硬盘录像机,本资源仅用个人使用 要求打开basic认证,web端口协议,要求f ...

  10. 安防视频推流组件EasyRTSPServer对接海康NVR视频正常音频不能正常播放问题解析

    背景分析 众所周知,RTSP协议是一个流媒体协议,可以实现直播和点播形式的音频与视频流的播放.RTSP协议定义了多种服务器-客户端之间交互的接口,主要有OPTIONS,DESCRIBE,SETUP,P ...

最新文章

  1. Spring中复杂类型注入
  2. excelvba怎么设置不打开文件自动保存_自从有了这个工具,我的Office操作已经快到慢不下来了!(升级篇)...
  3. PS教程:如何批量处理图片
  4. YTU 3003: 括号匹配(栈和队列)
  5. 32位/64位机上常用数据类型字节数(C语言)
  6. hiho1015(kmp+统计出现次数)
  7. Matter-JS friction 摩擦力
  8. sphinx的php扩展,替php安装sphinx扩展
  9. 远控免杀从入门到实践(2)工具总结篇
  10. 总结:Python 轻量级序列化和反序列化包 marshmallow 详细使用指南
  11. 期货基础知识(竞价,定价,保证金计算)
  12. PHP解压zip文件,并且读取文件内容输出
  13. Matlab分析系统的动态性能
  14. 实验一-Bomblab(炸弹实验)
  15. SQLserver基础--语句、存储过程(七)
  16. Python 计算思维训练——输入和错误处理练习(二)第三关
  17. 高斯判别分析 matlab,机器学习导论(5)–GDA高斯判别模型
  18. 华为nova7se能云闪付吗_华为nova7se支持NFC功能吗?可以用NFC来刷公交卡吗
  19. Web3创业具备创新爆炸式增长的所有要素
  20. 引文分析工具HistCite Pro与CiteSpace的安装

热门文章

  1. qq相册回收站复原显示服务器繁忙,qq回收站照片怎么找回?3大恢复方法3分钟解决...
  2. Python 绘制属于你的世界地图
  3. 利用lnmp一键安装的php环境忘记mysql,root用户密码解决方法
  4. 软考中级软件设计师-计算机系统知识点速查
  5. 三极管基极限流电阻计算
  6. 如何安装pygame模块
  7. 数字日期格式转换yyyymmdd_js时间转换,能够把时间转换成yyyymmdd格式或yyyymm格式...
  8. 上位机和下位机笔记总结
  9. fdfs文件服务环境搭建详细教程
  10. itextPDF生成表格的pdf