ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-02-07 15:33:36  阅读:431  来源: 互联网

标签:HCNetSDK NVR byte 海康 int 人脸 NET public DVR


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

硬件:海康超脑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顺序要和结构体中定义的顺序保持一致
        @Override
        protected 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);
        //用户注销,释放SDK
        test01.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,获取FDID
        lpOutputParam.read();
    	String xmlStr = lpOutputParam.lpOutBuffer.getString(0);
        // dom4j解析xml
        try {
            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解析xml
                try {
                    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顺序要和结构体中定义的顺序保持一致
        @Override
        protected 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 - 1
        public byte byAudioChanNum;    //语音通道数
        public byte byIPChanNum;     //最大数字通道个数,低位
        public byte byZeroChanNum;    //零通道编码个数 //2010-01-16
        public byte byMainProto;      //主码流传输协议类型 0-private, 1-rtsp,2-同时支持private和rtsp
        public byte bySubProto;        //子码流传输协议类型0-private, 1-rtsp,2-同时支持private和rtsp
        public 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-码流10
        public int dwLinkMode;// 0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-RTP/RTSP,5-RSTP/HTTP ,6- HRUDP(可靠传输) ,7-RTSP/HTTPS
        public 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时默认为1
        public 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; //保留,置为0
        public 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-GIF
        public 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或者ID
        public 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),获取命令成功时不会赋值,如果不需要,可以置NULL
        public 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_SetReconnect
    boolean 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- GIF
        netDvrSendParamIn.byPicType = 1;
        // 图片管理号,人脸库不支持,设为0
        netDvrSendParamIn.dwPicMangeNo = 0;
        // 图片播放时长,单位:秒,人脸库不支持,设为0
        netDvrSendParamIn.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) {
        // 图片ID
        String 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或者ID
            picID = 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:用户注销,释放SDK
        uploadFaceUtil.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>

标签:HCNetSDK,NVR,byte,海康,int,人脸,NET,public,DVR
来源: https://www.cnblogs.com/zhangwanpeng/p/15868031.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有