海康威视SDKjava二次开发身份证人脸识别

前言

本来一个很简单的SDK接口对接,折腾了好久;总结下原因有:

海康的SDK底层使用C++写的,我不熟悉C++;
海康Java源码示例写的是一个Swing桌面应用,我需要的是嵌入到web项目;
海康《设备网络SDK使用手册》中的示例是用C++写的;并且会出现使用手册和Java源码示例版本不匹配的情况(用手册版本高于Java源码示例版)  
我的需求

使用海康认证对面设备在刷身份证和人脸识别通过后,取到身份证信息和人脸照片并且传到页面上。
代码处理
1.将SDK开发包【库文件】里的HCNetSDK.dll、HCCore.dll、PlayCtrl.dll、SuperRender.dll、AudioRender.dll、HCNetSDKCom文件夹、ssleay32.dll、libeay32.dll文件均要加载到程序里面,【HCNetSDKCom文件夹】(包含里面的功能组件dll库文件)需要和HCNetSDK.dll、HCCore.dll一起加载,放在同一个目录下(我的事springboot项目,放在resources目录下),且HCNetSDKCom文件夹名不能修改。
2.HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(“E:\project\renliantext\src\main\resources\lib\HCNetSDK”, HCNetSDK.class);修改HCnetSDK的引入路径。
3.将路径:将Demo示例\4- Java 开发示例\2-报警布防监听\AlarmJavaDemo\src\alarmjavademo的demo包移植过来并且解决报错信息,就是导入包的问题 手动引入jar包或者从MAVEN再导入就好
4,写Service类,调用接口进行注册,布防。布防成功后设置报警回调函数
5,写serviceimp类,就是报警回调函数的实现在里面取到想要的数据。
下面是代码
Service类源码 里面有main方法 可以先进行测试看时候可以注册成功已经设置回到函数成功

	package com.jeeplus.modules.xwhj.haikang.service;

import com.jeeplus.modules.xwhj.haikang.HCNetSDK;
import com.jeeplus.modules.xwhj.haikang.Haikangimp;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.util.Timer;
import java.util.TimerTask;

@Service
public class Haikang {


static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
static  HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
static HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
static String m_sDeviceIP="192.168.19.249";//已登录设备的IP地址
static String m_sUsername="admin";//设备用户名
static String m_sPassword="xwkj0713";//设备密码

static int lUserID;//用户句柄
static int lAlarmHandle;//报警布防句柄
static int lListenHandle;//报警监听句柄

 /*  FMSGCallBack fMSFCallBack;//报警回调函数实现
AlarmJavaDemoView.FMSGCallBack_V31 fMSFCallBack_V31;*///报警回调函数实现



public void logintext() {//GEN-FIRST:event_jButtonLoginActionPerformed

        hCNetSDK.NET_DVR_Init();

    //注册之前先注销已注册的用户,预览情况下不可注销
    if (lUserID > -1) {
        //先注销
        hCNetSDK.NET_DVR_Logout(lUserID);
        lUserID = -1;
    }

    //注册
    m_sDeviceIP = "192.168.19.249";
    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_sUsername = "admin";
    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_sPassword ="xwkj0713";

    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());

    m_strLoginInfo.wPort =8000;

    lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);

    if (lUserID == -1) {
        JOptionPane.showMessageDialog(null, "false,错误号:" +  hCNetSDK.NET_DVR_GetLastError());
    } else {
        JOptionPane.showMessageDialog(null, "success");
    }

}

/*public static void main(String[] args){

   *//* while (1>0){
        System.out.println("~");
    }*//*
};*/



public void initMemberFlowUpload(){
    // 初始化
    hCNetSDK.NET_DVR_Init();
    //设置连接时间与重连时间
    hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
    hCNetSDK.NET_DVR_SetReconnect(10000, true);
    // 注册设备-登录参数,包括设备地址、登录用户、密码等
    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.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());

    m_strLoginInfo.wPort = 8000;
    m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
    //设备信息, 输出参数
    final int  lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo,m_strDeviceInfo);
    System.out.println("lUserID.size-->" + lUserID);
    if(lUserID< 0){
        System.out.println("hCNetSDK.NET_DVR_Login_V30()"+"\n" +hCNetSDK.NET_DVR_GetErrorMsg(null));
        hCNetSDK.NET_DVR_Cleanup();
        System.out.println("注册失败");
        return;
    }


    //设置报警回调函数
    boolean  callflag = hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(new Haikangimp(),null );
    if(callflag){
        System.out.println("callback----success+设置回调函数成功");
    }

    //启用布防-其他报警布防参数不需要设置,不支持
    HCNetSDK.NET_DVR_SETUPALARM_PARAM lpSetupParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
    lpSetupParam.byLevel=0;
    lpSetupParam.write();
    final   int lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID,lpSetupParam);
    if (lAlarmHandle< 0)
    {
        System.out.println("NET_DVR_SetupAlarmChan_V41 error, %d\n"+hCNetSDK.NET_DVR_GetLastError());
        hCNetSDK.NET_DVR_Logout(lUserID);
        hCNetSDK.NET_DVR_Cleanup();
        System.out.println("布防失败");
    }
    else {
        System.out.println("bufangsuccess++布防成功");
    }
    //等待过程中,如果设备上传报警信息,在报警回调函数里面接收和处理报警信息
   Timer timer =new Timer();// 实例化Timer类
    timer.schedule(new TimerTask() {
        public void run() {
            //撤销布防上传通道
            if (! hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle))
            {
                System.out.println("! hCNetSDK.NET_DVR_CloseAlarmChan_V31(lAlarmHandle)\n"+ hCNetSDK.NET_DVR_GetLastError() +"\n" +hCNetSDK.NET_DVR_GetErrorMsg(null) );
                hCNetSDK.NET_DVR_Logout(lUserID);
                hCNetSDK. NET_DVR_Cleanup();
                return;
            }
            //注销用户
            hCNetSDK.NET_DVR_Logout(lUserID);
            //释放SDK资源
            hCNetSDK.NET_DVR_Cleanup();
            this.cancel();
            System.gc();//主动回收垃圾
        }
        }, 100 * 60 * 1000 );// 这里毫秒


}}

源码2报警回调函数实现

package com.jeeplus.modules.xwhj.haikang;
import com.jeeplus.common.utils.CacheUtils;
import com.jeeplus.modules.xwhj.familyinfo.entity.TFamilyinfo;
import com.sun.jna.Pointer;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Haikangimp implements HCNetSDK.FMSGCallBack_V31 {

@Override
public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser ) {
    TFamilyinfo tFamilyinfo=new TFamilyinfo();
    String sAlarmType = new String();
    String[] newRow = new String[3];
    Date today = new Date();
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    String[] sIP = new String[2];
    switch (lCommand){
        case HCNetSDK.COMM_ID_INFO_ALARM: ///身份证信息*/
            HCNetSDK.NET_DVR_ID_CARD_INFO_ALARM strIDCardInfo = new HCNetSDK.NET_DVR_ID_CARD_INFO_ALARM();
            strIDCardInfo.write();
            Pointer pIDCardInfo = strIDCardInfo.getPointer();
            pIDCardInfo.write(0, pAlarmInfo.getByteArray(0, strIDCardInfo.size()), 0, strIDCardInfo.size());
            strIDCardInfo.read();

            sAlarmType = sAlarmType + ":门禁身份证刷卡信息,身份证号码:" + new String(strIDCardInfo.struIDCardCfg.byIDNum).trim() + ",姓名:" +
                    new String(strIDCardInfo.struIDCardCfg.byName).trim() + ",报警主类型:" + strIDCardInfo.dwMajor + ",报警次类型:" + strIDCardInfo.dwMinor;

             String s =new String(strIDCardInfo.struIDCardCfg.byName).trim();
            /*System.out.println(sAlarmType);*/
            newRow[0] = dateFormat.format(today);



            String name=new String(strIDCardInfo.struIDCardCfg.byName).trim();
            String cardnum=new String(strIDCardInfo.struIDCardCfg.byIDNum).trim();
            String address=new String(strIDCardInfo.struIDCardCfg.byAddr).trim();
            tFamilyinfo.setHjyhm(name);
            tFamilyinfo.setZjhm(cardnum);
            tFamilyinfo.setJtmx(address);


            //报警类型
            newRow[1] = sAlarmType;
            //报警设备IP地址
            sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
            newRow[2] = sIP[0];

            //身份证图片
            if (strIDCardInfo.dwPicDataLen > 0) {
                SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
                String newName = sf.format(new Date());
                FileOutputStream fout;
                try {
                    String filename ="D:\\Program Files\\TortoiseSVN\\bin\\xbhj\\userfiles\\1\\xwhj\\" +

                            newName + "_IDInfoPic.jpg";
                    fout = new FileOutputStream(filename);
                    //将字节写入文件
                    long offset = 0;
                    ByteBuffer buffers = strIDCardInfo.pPicData.getByteBuffer(offset, strIDCardInfo.dwPicDataLen);
                    byte[] bytes = new byte[strIDCardInfo.dwPicDataLen];
                    buffers.rewind();
                    buffers.get(bytes);
                    fout.write(bytes);
                    fout.close();
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


            if (strIDCardInfo.dwCapturePicDataLen > 0) {
                SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
                String newName = sf.format(new Date());
                FileOutputStream fout;
                try {
                    String filename = "D:\\Program Files\\TortoiseSVN\\bin\\xbhj\\userfiles\\1\\xwhj\\"  +
                             newName + "_IDInfoCapturePic.jpg";
                    tFamilyinfo.setYhzp(filename);
                    fout = new FileOutputStream(filename);
                    //将字节写入文件
                    long offset = 0;
                    ByteBuffer buffers = strIDCardInfo.pCapturePicData.getByteBuffer(offset, strIDCardInfo.dwCapturePicDataLen);
                    byte[] bytes = new byte[strIDCardInfo.dwCapturePicDataLen];
                    buffers.rewind();
                    buffers.get(bytes);
                    fout.write(bytes);
                    fout.close();
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                CacheUtils.put("hkidcard",tFamilyinfo);
            }
            break;
    }
        return true;
    }}

以上就是全部的代码里 里面有我的项目里的一些实体类可以忽略不计。改成你自己的就好了 遇到问题的小伙伴可以看下 提供一个思路 ,毕竟对接的时候我也是一脸懵逼 研究了一段时间看到别人写的一些东西才调通设备,希望能给其他人一些帮助~~就这吧 加油了嘿嘿 = =

你可能感兴趣的:(海康设备对接,java,websocket,智能合约)