java调用海康SDK的一点体会

1、首先需要到海康网站上下载海康的sdk、库文件、demo程序、接口说明文档。

在这里插入图片描述
解压后的目录
在这里插入图片描述
接口说明文档
在这里插入图片描述
其实java通过sdk调用海康接口,不是很好的方式,使用API方式更简单一点。sdk的方式,其实是通过中间JNA的封装,直接调用底层的C++函数,因此需要导入jna包,需要c++的动态库。怎样初始化sdk和动态库,在下载的文档里有说明。需要的jna在这:

SDKV6.1.9.48_win64\Demo示例\4- Java 开发示例\1-预览回放下载\ClientDemo\lib\

完整demo:https://gitee.com/hb868_admin/public.git

maven里面引入这两个包

 <dependency>
        <groupId>com.sun.jna</groupId>
        <artifactId>jna</artifactId>
        <version>3.0.9</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/jna.jar</systemPath>
    </dependency>
    <dependency>
        <groupId>com.sun.jna.examples</groupId>
        <artifactId>jna</artifactId>
        <version>3.0.9</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/examples.jar</systemPath>
</dependency>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>你的springboot启动类</mainClass>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

修改sdk的地方:
boolean NET_DVR_CaptureJPEGPicture(int lUserID, int lChannel, NET_DVR_JPEGPARA lpJpegPara, byte[] sPicFileName);
改为(修改文件路径为字符串):
boolean NET_DVR_CaptureJPEGPicture(int lUserID, int lChannel, NET_DVR_JPEGPARA lpJpegPara, String sPicFileName);

否则截图文件名乱码。

这个截图接口,需要预览界面,不能在后台用:

BOOL NET_DVR_CapturePicture(
  LONG    lRealHandle,
  char    *sPicFileName
);

添加预置位查询结构体:
public static class NET_DVR_PRESET_NAMES extends Structure {
public NET_DVR_PRESET_NAME[] presets=new NET_DVR_PRESET_NAME[300];
}

另外一个截图保存到内存里也是可以的:

 /**
             下面方法图片先读到内存测试  也可以
            IntByReference realSize = new IntByReference(0);
            HCNetSDK.BYTE_ARRAY picByte = new HCNetSDK.BYTE_ARRAY(1024*1024);
            picByte.write();
            Pointer pByte = picByte.getPointer();

            boolean fs = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(device.getLUserID(), 1, jpgParams, pByte,1024*1024,realSize );
            picByte.read();

            try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath));){
                outputStream.write(picByte.byValue, 0, realSize.getValue());
                outputStream.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }*/

主要代码(包括云台控制、截屏录像,没有红外测温):

对接sdk的类:

package com.client;

import com.alibaba.fastjson2.JSONObject;
import com.common.OSSelect;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
public class NVR_SDK {

    private static  HCNetSDK hCNetSDK = null;
    private static final String LIB_PATH = System.getProperty("user.dir") + "/so/hc/";


    //异常消息回调
    private static final  HCNetSDK.FExceptionCallBack fExceptionCallBack = (dwType, lUserID, lHandle, pUser) -> {
        log.error("异常事件类型:{}", dwType );
    };


    public static boolean init() {
        try {
            if (hCNetSDK == null) {
                System.out.println("开始执行海康威视SDK初始化");
                log.info("开始执行海康威视SDK初始化");
                if (!CreateSDKInstance()) {
                    log.error("海康威视SDK初始化.....fail");
                    return false;
                }
            }else{
                return true;
            }
            if (!OSSelect.isWindows()) {
                log.info("我进来了 !OSSelect.isWindows()");
                //linux系统建议调用以下接口加载组件库
                HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
                HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
                //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
                String strPath1 = LIB_PATH + "libcrypto.so.1.1";
                String strPath2 = LIB_PATH + "libssl.so.1.1";

                System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
                ptrByteArray1.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());

                System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
                ptrByteArray2.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());

                String strPathCom = LIB_PATH;
                HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
                System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
                struComPath.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
            }

            //SDK初始化,一个程序只需要调用一次
            if (hCNetSDK.NET_DVR_Init()) {
                log.info("我进来了 hCNetSDK.NET_DVR_Init()");
                if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, null)) {
                    log.error("设置异常消息回调失败");
                    return false;
                }else{
                    log.info("设置异常消息回调成功");
                }

                log.info("海康威视SDK初始化成功 ... OK");
                return true;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        log.error("海康威视SDK初始化失败 ... fail");
        return false;
    }




    /**
     * 动态库加载
     *
     * @return
     */
    private static boolean CreateSDKInstance() {
        log.info("开始加载海康威视本地链接库");
        if (hCNetSDK == null) {
            synchronized (HCNetSDK.class) {
                try {
                    //Linux系统加载库路径
                    String strDllPath = LIB_PATH + "libhcnetsdk.so";
                    log.info("加载海康威视本地链接库 -> {}", strDllPath);
                     if (OSSelect.isWindows()) {
                         //     //win系统加载库路径
                         strDllPath = System.getProperty("user.dir") +"/dac/haikang/windows/HCNetSDK.dll";
                         strDllPath = strDllPath.replaceAll("/", "\\\\");
                         log.info("成功加载海康威视本地链接库 -> {} ...OK", strDllPath);
                     }

                    hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);

                    return true;
                } catch (Exception ex) {
                    log.error("加载海康威视本地链接库失败, 错误码:{}", ex.getMessage());
                }
            }
        }
        return false;
    }

    public static Tuple<Boolean, HCNetSDK.NET_DVR_DEVICEINFO_V40> login_V40(HkNvrDevice device) {

        //注册
        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();//设备信息

        String m_sDeviceIP = device.getHost();//设备ip地址
        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());

        String m_sUsername = device.getUsername();//设备用户名
        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());

        String m_sPassword = device.getPassword();//设备密码
        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 = (short) device.getPort().intValue();
        System.out.println(m_strLoginInfo.wPort);
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
        m_strLoginInfo.byLoginMode=0;  //0- SDK私有协议,1- ISAPI协议
        // write()调用后数据才写入到内存中
        m_strLoginInfo.write();

        device.lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (device.lUserID == -1) {
            log.error("用户[{}]登录失败,错误码为:{}", device.getUsername(), hCNetSDK.NET_DVR_GetLastError());
            return Tuple.of(false);
        }else{
            log.info("用户[{}]登录设备[{}]成功{}",device.getUsername(),device.getHost(),device.getDeviceCode());
        }
        // read()后,结构体中才有对应的数据
        m_strDeviceInfo.read();

        return Tuple.of(true, m_strDeviceInfo);
    }

    //设备注销 SDK释放
    public static void logout(HkNvrDevice device) {
        if (device.lUserID > -1) {
            hCNetSDK.NET_DVR_Logout(device.lUserID);
            device.setLUserID(-1);
            log.info("用户[{}]成功从设备[{}]上注销", device.getUsername(), device.getDeviceCode());
        }
    }

    public static void destroy() {
        try {
            //SDK反初始化,释放资源,只需要退出时调用一次
            if(hCNetSDK != null){
                hCNetSDK.NET_DVR_Cleanup();
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        log.info("海康威视SDK成功销毁");
    }



    public static void record(HkNvrDevice device, int lChannel, int saveTimeSeconds){

        int lPlay = -1;
        device.recording.clear();
        device.stopRecord.clear();

        log.info("NVR设备[{}]视频预览...", device.getDeviceCode());
        device.isRecording.getAndSet(true);
        try {
            if(device.getLUserID()<0) {
                device.loginDevice();
            }
            HCNetSDK.NET_DVR_PREVIEWINFO strClientInfo = new HCNetSDK.NET_DVR_PREVIEWINFO();
            strClientInfo.read();
            strClientInfo.hPlayWnd = 0;  //窗口句柄,从回调取流不显示一般设置为空
            strClientInfo.lChannel = lChannel;  //通道号
            //strClientInfo.lChannel = device.getM_strDeviceInfo().struDeviceV30.byStartDChan;  //通道号
            strClientInfo.dwStreamType = 0; //0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推
            strClientInfo.dwLinkMode = 0;   //连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输),7-RTSP/HTTPS,8-NPQ
            strClientInfo.bBlocked = 1;     //0-非阻塞取流,1-阻塞取流
            strClientInfo.write();

            lPlay = hCNetSDK.NET_DVR_RealPlay_V40(device.lUserID, strClientInfo, null, null);
            if (lPlay == -1) {
                int iErr = hCNetSDK.NET_DVR_GetLastError();
                log.error("NVR设备[{}]视频预览失败, 错误码:{}", device.getDeviceCode(), iErr);
            }
            log.info("NVR设备[{}]视频预览成功 ... OK", device.getDeviceCode());

            String token = System.currentTimeMillis()+"";

            String mp4File = "d:\\demo"+".mp4";

            if (hCNetSDK.NET_DVR_SaveRealData_V30(lPlay, 2, mp4File)) {
                log.info("NVR设备[{}]录像成功, 正在生成录像文件: {}", device.getDeviceCode(), mp4File);
                device.tokenRecording = token;
                device.mp4File = mp4File;
                device.recording.offer(token);
                try {
                    device.stopRecord.poll(saveTimeSeconds, TimeUnit.SECONDS);
                } catch (Exception e) {
                    log.error(e.getMessage());
                } finally {
                    log.info("NVR设备[{}]正在关闭视频预览...", device.getDeviceCode());
                    if(hCNetSDK.NET_DVR_StopRealPlay(lPlay)){
                        log.info("NVR设备[{}]成功关闭视频预览 ... OK", device.getDeviceCode());
                    }else{
                        log.error("NVR设备[{}]关闭视频预览失败 ... fail", device.getDeviceCode());
                    }
                }
            } else {
                int iErr = hCNetSDK.NET_DVR_GetLastError();
                log.error("NVR设备[{}]开启录像失败, 错误码:{} ... fail", device.getDeviceCode(), device.getDeviceCode(), iErr);
            }

        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (lPlay != -1) {
                log.info("NVR设备[{}]正在关闭视频预览...", device.getDeviceCode());
                if(hCNetSDK.NET_DVR_StopRealPlay(lPlay)){
                    log.info("NVR设备[{}]成功关闭视频预览 ... OK", device.getDeviceCode());
                }else{
                    log.error("NVR设备[{}]关闭视频预览失败 ... fail", device.getDeviceCode());
                }
            }
            device.recording.clear();
            device.stopRecord.clear();

            device.isRecording.getAndSet(false);
        }
    }


    public static Tuple<Boolean, String> stopRecord(HkNvrDevice device,  String token) {
        if(!device.isRecording.get()){
            log.info("NVR设备[{}]录像...", device.getDeviceCode());
        }
        if(!token.equals(device.tokenRecording)){
            return Tuple.of(false);
        }
        device.stopRecord.offer(1);

        if(!device.isRecording.get()){
            log.info("NVR设备[{}]成功停止录像 ...OK", device.getDeviceCode());
        }
        return Tuple.of(true, device.mp4File);
    }

    /**
     *  云台控制
     * @param device
     * @param lChannel
     * @param dwPTZCommand
     * @return
     */
    public static boolean ptzControl(HkNvrDevice device, int lChannel, int dwPTZCommand){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        boolean rs = hCNetSDK.NET_DVR_PTZControlWithSpeed_Other(device.getLUserID(),lChannel,dwPTZCommand,0,4);
        if(!rs){
            log.error("NVR设备[{}]云台控制失败,错误码[{}]...", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
            return false;
        }
        return rs;
    }

    /**
     * 停止云台转动
     * @param device
     * @param lChannel
     * @param dwPTZCommand
     * @return
     */
    public static boolean ptzControlStop(HkNvrDevice device, int lChannel, int dwPTZCommand){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        //停止
        return hCNetSDK.NET_DVR_PTZControlWithSpeed_Other(device.getLUserID(),lChannel,dwPTZCommand,1,5);
    }

    /**
     *  获取球机位置
     * @param device
     * @param lChannel
     * @return
     */
    public static JSONObject getPTZConfig(HkNvrDevice device, int lChannel){
        if(device.getLUserID()<0){
            device.loginDevice();
        }

        /**
         * short wPanPos;//水平参数
         * short wTiltPos;//垂直参数
         * short wZoomPos;//变倍参数
         */
        JSONObject object = new JSONObject();
        HCNetSDK.NET_DVR_PTZPOS ptzVO = new HCNetSDK.NET_DVR_PTZPOS();
        ptzVO.write();
        IntByReference lpBytesReturned = new IntByReference(1);
        boolean rs = hCNetSDK.NET_DVR_GetDVRConfig(device.getLUserID(), HCNetSDK.NET_DVR_GET_PTZPOS, lChannel, ptzVO.getPointer(), ptzVO.size(),  lpBytesReturned);
        if(!rs){
            log.error("设备[{}]读取云台配置参数出错,错误码[{}]...", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }else{
            ptzVO.read();
            // 实际显示的PTZ值是获取到的十六进制值的十分之一
            object.put("yaw",ptzVO.wPanPos*0.1f);
            object.put("pitch",ptzVO.wTiltPos*0.1f);
            object.put("zoomValue",ptzVO.wZoomPos*0.1f);
        }

        return object;

    }


    /**
     * 云台设置球机位置PTZ
     *
     * HCNetSDK.NET_DVR_SetDVRConfig  HCNetSDK.NET_DVR_SET_PTZPOS
     *
     * HCNetSDK.NET_DVR_SET_PTZPOS.wAction
     * 操作类型,仅在设置时有效。1-定位PTZ参数,2-定位P参数,3-定位T参数,4-定位Z参数,5-定位PT参数
     * @param device
     * @param lChannel
     * @param params
     * @return
     */
    public static boolean setPTZConfig(HkNvrDevice device, int lChannel,JSONObject params){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        Object pitch = params.get("pitch"); //水平角位
        Object yaw = params.get("yaw"); // 垂直角度
        Object wZoomPos = params.get("zoomValue"); //变倍参数
        HCNetSDK.NET_DVR_PTZPOS ptzVO = new HCNetSDK.NET_DVR_PTZPOS();

        if(pitch!=null && yaw!=null && wZoomPos!=null){
            ptzVO.wAction=1;
            ptzVO.wPanPos = Short.parseShort(pitch.toString());
            ptzVO.wTiltPos =Short.parseShort(yaw.toString());
            ptzVO.wZoomPos =Short.parseShort(wZoomPos.toString());
        }else if(pitch!=null && yaw!=null){
            ptzVO.wAction=5;
            ptzVO.wPanPos = Short.parseShort(pitch.toString());
            ptzVO.wTiltPos =Short.parseShort(yaw.toString());
        }else if(pitch!=null){
            ptzVO.wAction=2;
            ptzVO.wPanPos = Short.parseShort(pitch.toString());
        }else if(yaw!=null){
            ptzVO.wAction=3;
            ptzVO.wTiltPos =Short.parseShort(yaw.toString());
        }else if(wZoomPos!=null){
            ptzVO.wAction=4;
            ptzVO.wZoomPos =Short.parseShort(wZoomPos.toString());
        }

        ptzVO.write();

        boolean rs = hCNetSDK.NET_DVR_SetDVRConfig(device.getLUserID(),  HCNetSDK.NET_DVR_SET_PTZPOS,  lChannel, ptzVO.getPointer(), ptzVO.size());

        if(!rs){
            log.error("设备[{}]云台设置PTZ位置出错,错误码[{}]...", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }
        return rs;

    }


    /**
     * 获取快球聚焦模式信息
     * @param device
     * @param lChannel
     * @return
     */
    public static HCNetSDK.NET_DVR_FOCUSMODE_CFG getFocusMode(HkNvrDevice device,int lChannel) {
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        HCNetSDK.NET_DVR_FOCUSMODE_CFG struFocusMode = new HCNetSDK.NET_DVR_FOCUSMODE_CFG();
        struFocusMode.read();
        struFocusMode.dwSize=struFocusMode.size();
        struFocusMode.write();

        boolean b_GetCameraParam=hCNetSDK.NET_DVR_GetDVRConfig(device.getLUserID(),HCNetSDK.NET_DVR_GET_FOCUSMODECFG,lChannel,
                struFocusMode.getPointer(),struFocusMode.size(),new IntByReference(0));
        if (!b_GetCameraParam) {
            log.error("设备[{}]获取快球聚焦模式失败,错误码:错误码[{}]", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }
        struFocusMode.read();
        log.info("设备[{}]聚焦模式:[{}]",device.getDeviceCode(),struFocusMode.byFocusMode);
        return  struFocusMode;
    }

    /**
     * 设置快球聚焦模式信息
     * @param device
     * @param lChannel
     * @param byFocusMode 0:自动,1:手动
     * @return
     */
    public static boolean setFocusMode(HkNvrDevice device,int lChannel,byte byFocusMode){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        HCNetSDK.NET_DVR_FOCUSMODE_CFG struFocusMode = getFocusMode(device,lChannel);
        struFocusMode.byFocusMode=byFocusMode;
        struFocusMode.byFocusDefinitionDisplay=1;
        struFocusMode.byFocusSpeedLevel=3;
        struFocusMode.write();
        boolean b_SetCameraParam=hCNetSDK.NET_DVR_SetDVRConfig(device.getLUserID(),
                HCNetSDK.NET_DVR_SET_FOCUSMODECFG,lChannel,struFocusMode.getPointer(),struFocusMode.size());
        if (!b_SetCameraParam) {
            log.error("设备[{}]设置快球聚焦模式失败,错误码:[{}]", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
            return false;
        }
        return true;
    }

    /**
     * 控制(数值)聚焦
     * @param device
     * @param lChannel
     * @param dwFocusPos
     * @return
     */
    public static boolean setDwFocusPos(HkNvrDevice device,int lChannel,int dwFocusPos){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        HCNetSDK.NET_DVR_FOCUSMODE_CFG struFocusMode = getFocusMode(device,lChannel);
        struFocusMode.dwFocusPos=dwFocusPos;
        struFocusMode.byFocusDefinitionDisplay=1;
        struFocusMode.byFocusSpeedLevel=3;
        struFocusMode.write();
        boolean b_SetCameraParam=hCNetSDK.NET_DVR_SetDVRConfig(device.getLUserID(),
                HCNetSDK.NET_DVR_SET_FOCUSMODECFG,lChannel,struFocusMode.getPointer(),struFocusMode.size());
        if (!b_SetCameraParam) {
            log.error("设备[{}]设置快球聚焦数值失败,错误码:[{}]", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
            return false;
        }
        return true;
    }


    /**
     * 读取设备配置详细信息
     * @param device
     * @return
     */
    public static HCNetSDK.NET_DVR_DEVICECFG_V40 getDeviceConf(HkNvrDevice device,int lChannel){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        HCNetSDK.NET_DVR_DEVICECFG_V40 po = new HCNetSDK.NET_DVR_DEVICECFG_V40();
        po.dwSize = po.size();
        po.write();
        boolean rs = hCNetSDK.NET_DVR_GetDVRConfig(device.getLUserID(),
                HCNetSDK.NET_DVR_GET_DEVICECFG_V40, lChannel,
                po.getPointer(),po.size(),new IntByReference(0));

        if (!rs) {
            log.error("设备[{}]读取设备配置详细信息失败,错误码:[{}]", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }
        po.read();
        return po;
    }

    /**
     *  云台预置点操作
     *
     * @param device
     * @param lChannel
     * @param dwPTZPresetCmd
     * SET_PRESET 8 设置预置点
     * CLE_PRESET 9 清除预置点
     * GOTO_PRESET 39 转到预置点
     *
     * @param dwPresetIndex
     * @return
     */
    public static boolean ptzPreset(HkNvrDevice device,int lChannel, int dwPTZPresetCmd, int dwPresetIndex){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
       boolean rs = hCNetSDK.NET_DVR_PTZPreset_Other(device.getLUserID(),lChannel,dwPTZPresetCmd,dwPresetIndex);
        if (!rs) {
            log.error("设备[{}]云台预置点操作失败,错误码:[{}]" , device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }
        return rs;
    }


    /**
     * 云台预置点列表
     * @param device
     * @param lChannel
     */
    public static List<Map<String, Object>> ptzPresetList(HkNvrDevice device,int lChannel){
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        List<Map<String, Object>> dList = new ArrayList<>();
        HCNetSDK.NET_DVR_PRESET_NAMES struPtTZPos = new HCNetSDK.NET_DVR_PRESET_NAMES();
        struPtTZPos.write();
        boolean b_GetPTZ = hCNetSDK.NET_DVR_GetDVRConfig(device.getLUserID(), HCNetSDK.NET_DVR_GET_PRESET_NAME, lChannel,
                struPtTZPos.getPointer(), struPtTZPos.size(), new IntByReference(1));
        if (!b_GetPTZ) {
            log.error("设备[{}]云台读取预置点操作失败,错误码:[{}]" , device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        } else {
            struPtTZPos.read();
            for (int i = 0; i <struPtTZPos.presets.length; i++) {
                if(struPtTZPos.presets[i].wPanPos!=0&&struPtTZPos.presets[i].wTiltPos!=0){
                    Map<String, Object> item = new HashMap<>();
                    item.put("num", struPtTZPos.presets[i].wPresetNum);
                    item.put("pitch",struPtTZPos.presets[i].wTiltPos*0.1);
                    item.put("yaw",struPtTZPos.presets[i].wPanPos*0.1);
                    item.put("channel",lChannel);
                    //item.put("zoomValue",struPtTZPos.presets[i].wZoomPos);
                    dList.add(item);
                }
            }
        }
        return  dList;
    }


    /**
     * 预览抓图
     * @param device
     * @param lChannel
     * @param filePath
     * @return
     */
    public static boolean capturePicture(HkNvrDevice device,int lChannel,String filePath) throws UnsupportedEncodingException {
        return capturePictureJpg( device, lChannel, filePath);
    }


    public static boolean capturePictureJpg(HkNvrDevice device,int lChannel,String filePath)  {
        {
            int lPlay = -1;
            if(device.getLUserID()<0) {
                device.loginDevice();
            }
            HCNetSDK.NET_DVR_PREVIEWINFO strClientInfo = new HCNetSDK.NET_DVR_PREVIEWINFO();
            strClientInfo.read();
            strClientInfo.hPlayWnd = 0;  //窗口句柄,从回调取流不显示一般设置为空
            strClientInfo.lChannel = lChannel;  //通道号
            strClientInfo.dwStreamType = 0; //0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推
            strClientInfo.dwLinkMode = 0;   //连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输),7-RTSP/HTTPS,8-NPQ
            strClientInfo.bBlocked = 1;     //0-非阻塞取流,1-阻塞取流
            strClientInfo.write();

            log.info("NVR设备[{}]用户登录句柄{},",device.getDeviceCode(),device.getLUserID());

            // 预览
            lPlay = hCNetSDK.NET_DVR_RealPlay_V40(device.getLUserID(), strClientInfo, null, null);

            if (lPlay < 0) {
                int iErr = hCNetSDK.NET_DVR_GetLastError();
                log.error("NVR设备[{}]视频预览失败, 错误码:{}", device.getDeviceCode(), iErr);
                return false;
            }

            log.info("NVR设备[{}]视频预览成功 ... OK", device.getDeviceCode());
            HCNetSDK.NET_DVR_JPEGPARA jpgParams = new HCNetSDK.NET_DVR_JPEGPARA();
            jpgParams.wPicQuality=0;
            jpgParams.wPicSize=4;
            jpgParams.write();

            boolean fs = hCNetSDK.NET_DVR_CaptureJPEGPicture(device.getLUserID(), lChannel, jpgParams, filePath);

            if (lPlay != -1) {
                log.info("NVR设备[{}]正在关闭视频预览...", device.getDeviceCode());
                if(hCNetSDK.NET_DVR_StopRealPlay(lPlay)){
                    log.info("NVR设备[{}]成功关闭视频预览 ... OK", device.getDeviceCode());
                }else{
                    log.error("NVR设备[{}]关闭视频预览失败 ... fail", device.getDeviceCode());
                }
            }

            /**
             下面方法图片先读到内存测试  也可以
            IntByReference realSize = new IntByReference(0);
            HCNetSDK.BYTE_ARRAY picByte = new HCNetSDK.BYTE_ARRAY(1024*1024);
            picByte.write();
            Pointer pByte = picByte.getPointer();

            boolean fs = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(device.getLUserID(), 1, jpgParams, pByte,1024*1024,realSize );
            picByte.read();

            try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath));){
                outputStream.write(picByte.byValue, 0, realSize.getValue());
                outputStream.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }*/


            if(!fs){
                log.error("NVR设备[{}]抓图失败, 错误码:{}", device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
            }

            return fs;

        }
    }

    /**
     * 海康设置前端参数
     * @param device
     * @param lChannel
     */
    public void CAMERAPARAMCFG(HkNvrDevice device,int lChannel) {
        if(device.getLUserID()<0){
            device.loginDevice();
        }
        HCNetSDK.NET_DVR_CAMERAPARAMCFG_EX struCameraParam=new HCNetSDK.NET_DVR_CAMERAPARAMCFG_EX();
        IntByReference ibrBytesReturned = new IntByReference(0);
        boolean b_GetCameraParam=hCNetSDK.NET_DVR_GetDVRConfig(device.getLUserID(),3368,lChannel,struCameraParam.getPointer(),struCameraParam.size(),ibrBytesReturned);
        if (!b_GetCameraParam) {
            log.error("设备[{}]获取前端参数失败,错误码:[{}]" , device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }
        struCameraParam.read();
        log.info("是否开启旋转:"+struCameraParam.struCorridorMode.byEnableCorridorMode);
        struCameraParam.struCorridorMode.byEnableCorridorMode=1;
        struCameraParam.write();
        boolean b_SetCameraParam=hCNetSDK.NET_DVR_SetDVRConfig(device.getLUserID(),3369,lChannel,struCameraParam.getPointer(),struCameraParam.size());
        if (!b_SetCameraParam) {
            log.error("设备[{}]设置前端参数失败,错误码:[{}]" , device.getDeviceCode(), hCNetSDK.NET_DVR_GetLastError());
        }
        struCameraParam.read();
    }


    /**
     *
     * @param device
     * @return
     */
    public static int getChannle(HkNvrDevice device){

        HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
        int lUserID = hCNetSDK.NET_DVR_Login_V30(device.getHost(), (short)device.getPort().intValue(),
                device.getUsername(), device.getPassword(), m_strDeviceInfo);

        HCNetSDK.NET_DVR_IPPARACFG m_strIpparaCfg = new HCNetSDK.NET_DVR_IPPARACFG();
        m_strIpparaCfg.write();
        boolean bRet  = hCNetSDK.NET_DVR_GetDVRConfig(device.lUserID, HCNetSDK.NET_DVR_GET_IPPARACFG, 0,
                m_strIpparaCfg.getPointer(), m_strIpparaCfg.size(), new IntByReference(0));
        m_strIpparaCfg.read();


        // 设备支持IP通道
        String sChannelName = "";
        if (!bRet) {
            // 设备不支持,则表示没有IP通道
            for (int iChannum = 0; iChannum < m_strDeviceInfo.byChanNum; iChannum++) {
                sChannelName = "Camera" + (iChannum + m_strDeviceInfo.byStartChan);
            }
        } else {
            // 设备支持IP通道
            for (int iChannum = 0; iChannum < m_strDeviceInfo.byChanNum; iChannum++) {
                if (m_strIpparaCfg.byAnalogChanEnable[iChannum] == 1) {
                    sChannelName = "Camera" + (iChannum + m_strDeviceInfo.byStartChan);
                }
            }
            for (int iChannum = 0; iChannum < HCNetSDK.MAX_IP_CHANNEL; iChannum++)
                if (m_strIpparaCfg.struIPChanInfo[iChannum].byEnable == 1) {
                    sChannelName = "IPCamera" + (iChannum + m_strDeviceInfo.byStartChan);
                }
        }

        int iChannelNum = -1;
        if (sChannelName.charAt(0) == 'C') {// Camara开头表示模拟通道
            // 子字符串中获取通道号
            iChannelNum = Integer.parseInt(sChannelName.substring(6));
        } else {
            if (sChannelName.charAt(0) == 'I') {// IPCamara开头表示IP通道,子字符创中获取通道号,IP通道号要加32
                iChannelNum = Integer.parseInt(sChannelName.substring(8)) + 32;
            } else {
                log.info("通道号获取失败");
                return -1;
            }
        }

        return iChannelNum;
    }

    /**
     * 海康获取IP通道
     * @param device
     */
    public void getIPInfo(HkNvrDevice device) {
        IntByReference ibrBytesReturned = new IntByReference(0);//获取IP接入配置参数
        HCNetSDK.NET_DVR_IPPARACFG_V40 m_strIpparaCfg = new HCNetSDK.NET_DVR_IPPARACFG_V40();
        m_strIpparaCfg.write();

        boolean bRet = hCNetSDK.NET_DVR_GetDVRConfig(device.getLUserID(), HCNetSDK.NET_DVR_GET_IPPARACFG_V40, 0,
                m_strIpparaCfg.getPointer(), m_strIpparaCfg.size(), ibrBytesReturned);
        m_strIpparaCfg.read();

        System.out.println("数字通道号:"+m_strIpparaCfg.dwStartDChan+",通道数量:"+m_strIpparaCfg.dwDChanNum);
    }
}

设备信息类

package com.client;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import com.client.HCNetSDK;
import com.client.NVR_SDK;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.time.LocalDateTime;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 海康威视的设备:NVR(网络硬盘录像机)
 */
@Slf4j
@EqualsAndHashCode(callSuper=false)
@Data
public class HkNvrDevice  {
    // 厂商ID:海康威视NVR(网络硬盘录像机)
    public static final String MANUFACTURER = "Hikvision";

    private String deviceCode;      // 设备编码

    private String deviceName;      // 设备名称
    private String manufacturer;          // 厂商ID
    private String manufacturerName;      // 厂商名称
    private String host;            // 设备ip
    private Integer port;               // 设备端口

    private Integer kind;           // 设备类别: 1-摄像机,2-硬盘录像机(NVR)
    private String model;           // 设备型号
    private String serialNumber; // 序列号/出厂编号

    // @JSONField(serialize = false)
    private String username;    // 登录设备的用户名
    // @JSONField(serialize = false)
    private String password; // 登录设备的密码

    private Integer source;     // 创建时的来源: 0-站端; 1-同步;
    private String nvrDeviceCode; // 当前摄像机连接的网络硬盘录像机的设备编码

    private Integer status;     // 上下线状态: 0-下线;1-上线
    private LocalDateTime createdTime; // 创建日期
    private String remark;  // 设备备注
    private String token;  // 设备备注

    @JSONField(serialize = false)
    public int lUserID = -1;


    // 海康威视NVR登录后获得的设备信息
    @JSONField(serialize = false)
    private HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo;


    @JSONField(serialize = false)
    public final BlockingQueue<String> recording = new ArrayBlockingQueue<>(1);


    @JSONField(serialize = false)
    public final BlockingQueue<Integer> stopRecord = new ArrayBlockingQueue<>(1);


    @JSONField(serialize = false)
    public String tokenRecording;


    @JSONField(serialize = false)
    public String mp4File;


    @JSONField(serialize = false)
    public final AtomicBoolean isRecording = new AtomicBoolean(false);


    public String getManufacturer() {
        return MANUFACTURER;
    }

    // 用户登录设备
    public boolean loginDevice() {
        NVR_SDK.init();
        // 登录设备
        Tuple<Boolean, HCNetSDK.NET_DVR_DEVICEINFO_V40> tuple = NVR_SDK.login_V40(this);
        if(tuple.getFirst()){
            this.setM_strDeviceInfo(tuple.getSecond());

            if (log.isInfoEnabled()){
                log.info("用户登录设备[{}]成功,设备上线成功: device -> {} ...OK", getDeviceCode(), JSON.toJSONString(this));
            }
        }else{
            log.error("用户登录设备[{}]失败,设备上线失败: device -> {} ...fail",getHost()+":::"+ getDeviceCode(), JSON.toJSONString(this));
        }
        return tuple.getFirst();
    }

    // 用户从设备中注销
    public boolean logoutDevice() {
        NVR_SDK.logout(this);
        if (log.isInfoEnabled()){
            log.info("用户注销设备[{}]成功: device -> {} ...OK", getDeviceCode(), JSON.toJSONString(this));
        }
        this.setLUserID(-1);
        return true;
    }

    @Override
    public String toString() {
        return super.toString();
    }


    public void destroy() {
        this.setLUserID(-1);
        if (log.isInfoEnabled()) {
            log.info("成功销毁Device[{}] ...OK", getDeviceCode());
        }
    }
}

辅助类

package com.client;

import lombok.NonNull;

import java.io.Serializable;

/**
 * 二阶元组
 *
 * @author liangwm
 * @since 2021-10-30
 */
public class Tuple<T, U> extends CloneSupport<Tuple<T, U>> implements Serializable {
    private static final long serialVersionUID = -1L;

    @NonNull
    private final T first;

    private final U second;

    public static <T, U> Tuple<T, U> of(T first, U second) {
        return new Tuple<>(first, second);
    }

    public static <T, U> Tuple<T, U> of(T first) {
        return new Tuple<>(first);
    }

    public Tuple(T first) {
        this(first, null);
    }

    public Tuple(T first, U second) {
        this.first = first;
        this.second = second;
    }

    @NonNull
    public T getFirst() {
        return first;
    }

    public U getSecond() {
        return second;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Tuple{");
        sb.append("first=").append(first);
        sb.append(", second=").append(second);
        sb.append('}');
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Tuple<?, ?> tuple = (Tuple<?, ?>) o;

        if (!first.equals(tuple.first)) return false;
        return second != null ? second.equals(tuple.second) : tuple.second == null;
    }

    @Override
    public int hashCode() {
        int result = first.hashCode();
        result = 31 * result + (second != null ? second.hashCode() : 0);
        return result;
    }
}
package com.client;
/**
 * 克隆支持类,提供默认的克隆方法
 * @author Looly
 *
 * @param <T> 继承类的类型
 */
public class CloneSupport<T> implements Cloneable<T>{

    @SuppressWarnings("unchecked")
    @Override
    public T clone() {
        try {
            return (T) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

}

package com.client;

/**
 * 克隆支持接口
 * @author Looly
 *
 * @param <T> 实现克隆接口的类型
 */
public interface Cloneable<T> extends java.lang.Cloneable{

    /**
     * 克隆当前对象,浅复制
     * @return 克隆后的对象
     */
    T clone();
}

注意:sdk默认的登录端口是8000,cosole页面登录端口是80。红外测温需要相机支持,而且在cosole有相关配置,使用通道一般是2

另外找的两个关于红外测温的类,没有测试:

package com.client;

import com.client.HCNetSDK;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

/**
 * 调用demo
 *
 * @author JW
 * @version 1.0
 * @date 2021/3/25 14:47
 */
@Slf4j
public class HKNetTemperature {
    private static String ip="192.168.8.14";
	private short port=8000;
	private static String username="";
	private static String password="";

	private int lUserID = -1;// 用户句柄
	private HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;// 设备信息

	static HCNetSDK hCNetSDK = null;// sdk

	public static synchronized void loadLibrary(String libraryPath) {
		if (null == hCNetSDK) {
			hCNetSDK = (HCNetSDK) Native.loadLibrary(libraryPath, HCNetSDK.class);
		}
	}

	public static void main(String[] args) {
		loadLibrary(System.getProperty("user.dir")+"\\lib\\HCNetSDK.dll");

		HKNetTemperature hkNetApp = new HKNetTemperature();

		System.out.println("---------------------ok----------------");

		if (hkNetApp.init() && hkNetApp.login()) {
			Float temperature = hkNetApp.getTemperature(new HKPoint(10.0f, 1.0f), 126, 100);
			log.info("1,1点的温度是,{}", temperature);
		}else{
			System.out.println("------------------err----------------");
		}

		hkNetApp.logout();
		hCNetSDK.NET_DVR_Cleanup();
	}

	/**
	 * SDK初始化
	 * 
	 * @return
	 */
	public Boolean init() {
		if (!hCNetSDK.NET_DVR_Init()) {
			log.error("初始化失败");
			return false;
		}
		return true;
	}

	/*************************************************
	 * 函数: "注册" 按钮单击响应函数 函数描述: 注册登录设备
	 *************************************************/
	public Boolean login() {// GEN-FIRST:event_jButtonLoginActionPerformed
		// 注册之前先注销已注册的用户,预览情况下不可注销
		if (lUserID > -1) {
			// 先注销
			hCNetSDK.NET_DVR_Logout_V30(lUserID);
		}
		// 注册
		m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();

		lUserID = hCNetSDK.NET_DVR_Login_V30(ip, port, username, password, m_strDeviceInfo);

		long userID = lUserID;
		boolean initSuc = hCNetSDK.NET_DVR_SetLogToFile(3, "f:\\sdklog\\", false);

		if (userID == -1) {
			System.out.println("登录失败,"+hCNetSDK.NET_DVR_GetLastError());
			log.error("登录失败,{}", hCNetSDK.NET_DVR_GetLastError());
			return false;
		}
		return true;
	}

	public void logout() {
		hCNetSDK.NET_DVR_Logout_V30(lUserID);
	}

	public Float getTemperature(HKPoint hkPoint, int sourceWidth, int sourceHeight) {
		HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO m_struThermometryInfo = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO();
		m_struThermometryInfo.dwSize = m_struThermometryInfo.size();

		HCNetSDK.NET_DVR_THERMOMETRY_COND m_struThermometryCond = new HCNetSDK.NET_DVR_THERMOMETRY_COND();
		m_struThermometryCond.dwSize = m_struThermometryCond.size();
		m_struThermometryCond.dwChannel = 1;
		m_struThermometryCond.wPresetNo = 1;
		m_struThermometryCond.write();

		HCNetSDK.NET_DVR_STD_CONFIG struCfg = new HCNetSDK.NET_DVR_STD_CONFIG();
		struCfg.lpCondBuffer = m_struThermometryCond.getPointer();
		struCfg.dwCondSize = m_struThermometryCond.size();
		struCfg.lpOutBuffer = m_struThermometryInfo.getPointer();
		struCfg.dwOutSize = m_struThermometryInfo.size();

		HCNetSDK.BYTE_ARRAY m_szStatusBuf = new HCNetSDK.BYTE_ARRAY(4096 * 4);
		struCfg.lpStatusBuffer = m_szStatusBuf.getPointer();
		struCfg.dwStatusSize = 4096 * 4;
		struCfg.byDataType = 0;

		boolean bRet = hCNetSDK.NET_DVR_GetSTDConfig(lUserID, 3624, struCfg);
		if (!bRet) {
			log.error("NET_DVR_GetSTDConfig失败,{}", hCNetSDK.NET_DVR_GetLastError());
			return 0f;
		}

		m_struThermometryInfo.dwSize = m_struThermometryInfo.size();
		m_struThermometryInfo.wPresetNo = 1;
		m_struThermometryInfo.struPresetInfo[0] = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO_PARAM();
		m_struThermometryInfo.struPresetInfo[0].byEnabled = 1;
		m_struThermometryInfo.struPresetInfo[0].byRuleID = 1;
		m_struThermometryInfo.struPresetInfo[0].wDistance = 10;
		m_struThermometryInfo.struPresetInfo[0].fEmissivity = (float) 0.9599;
		m_struThermometryInfo.struPresetInfo[0].byReflectiveEnabled = 0;
		m_struThermometryInfo.struPresetInfo[0].fReflectiveTemperature = 20;
		m_struThermometryInfo.struPresetInfo[0].byRuleCalibType = 2;
		// m_struThermometryInfo.struPresetInfo[0].szRuleName ="1";
		m_struThermometryInfo.struPresetInfo[0].byDistanceUnit = 0;
		// m_struThermometryInfo.struPresetInfo[0].byemissivityMode = 0;
		m_struThermometryInfo.struPresetInfo[0].struPoint = new HCNetSDK.NET_VCA_POINT();
		m_struThermometryInfo.struPresetInfo[0].struPoint.fX = 0;
		m_struThermometryInfo.struPresetInfo[0].struPoint.fY = 0;
		m_struThermometryInfo.struPresetInfo[0].struPoint.write();
		m_struThermometryInfo.struPresetInfo[0].struRegion = new HCNetSDK.NET_VCA_POLYGON();
		m_struThermometryInfo.struPresetInfo[0].struRegion.dwPointNum = 2;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0] = new HCNetSDK.NET_VCA_POINT();
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fX = (float) 0.187;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fY = (float) 0.6119;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].write();
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1] = new HCNetSDK.NET_VCA_POINT();
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fX = (float) 0.876;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fY = (float) 0.569;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].write();
		m_struThermometryInfo.struPresetInfo[0].struRegion.write();
		m_struThermometryInfo.write();
		struCfg.lpInBuffer = m_struThermometryInfo.getPointer();
		struCfg.dwInSize = m_struThermometryInfo.size();

		boolean setSTDConfig = hCNetSDK.NET_DVR_SetSTDConfig(lUserID, 3625, struCfg);
		log.info("NET_DVR_SetSTDConfig,{}", setSTDConfig);

		HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppenData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA();
		m_strJpegWithAppenData.dwSize = m_strJpegWithAppenData.size();
		m_strJpegWithAppenData.dwChannel = 1;
		HCNetSDK.BYTE_ARRAY ptrJpegByte    = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
		HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
		m_strJpegWithAppenData.pJpegPicBuff = ptrJpegByte.getPointer();
		m_strJpegWithAppenData.pP2PDataBuff = ptrP2PDataByte.getPointer();

		bRet = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, 2, m_strJpegWithAppenData);

		if (bRet) {
			// 测温数据
			if (m_strJpegWithAppenData.dwP2PDataLen > 0) {
				HKPoint point = point2point(hkPoint, sourceWidth, sourceHeight, m_strJpegWithAppenData.dwJpegPicWidth,
						m_strJpegWithAppenData.dwJpegPicHeight);
				return getTemperature0(m_strJpegWithAppenData.pP2PDataBuff
						.getByteBuffer((long) ((m_strJpegWithAppenData.dwJpegPicWidth * point.y + point.x) * 4), 4));
			}
		}

		return 0f;
	}

	private Float getTemperature0(ByteBuffer byteBuffer) {
		byte[] byTempData = new byte[4];
		byteBuffer.get(byTempData);

		int l = byTempData[0];
		l &= 0xff;
		l |= ((long) byTempData[1] << 8);
		l &= 0xffff;
		l |= ((long) byTempData[2] << 16);
		l &= 0xffffff;
		l |= ((long) byTempData[3] << 24);

		return Float.intBitsToFloat(l);
	}

	private HKPoint point2point(HKPoint points, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) {
		points.x = points.x * sourceWidth / targetWidth;
		points.y = points.y * sourceHeight / targetHeight;

		points.x = points.x >= targetWidth ? targetWidth : points.x;
		points.x = points.x < 0 ? 0 : points.x;

		points.y = points.y >= targetHeight ? targetHeight : points.y;
		points.y = points.y < 0 ? 0 : points.y;

		return points;
	}
}
package com.client;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;

/**
 * java解析海康摄像机二进制数据获取红外全屏温度
 */
public class ReadTempFromPic {

    public static void main(String[] args) throws IOException {
        String path = "D:\\桌面1\\双圆轨\\红外测温\\hot_M1PL0006_36517_00_002_545_18396_100_2024_03_28_16_24_53.csv";
        String s = ReadTempFromPic.handleImageData(path, 640);
        System.out.println("path--" + s);
        int x = 0;
        int y = 0;
        int width = 1;
        int height = 1;
        Double jsonHeightTemp = ReadTempFromPic.getJsonHeightTemp(s, x, y, width, height);
        System.out.println("jsonHeightTemp--" + jsonHeightTemp);
    }


    // 根据红外二进制原始图片 获取全屏温度
    public static String handleImageData(String srcPath, int width){
        int k = srcPath.indexOf(".");
        if (k == -1){
            return null;
        }
        // 目标文件
        String desPath = srcPath.substring(0, k) + ".json";

        File file = new File(srcPath);
        if (!file.exists()){
            return null;
        }
        // 65, 13, -88, 65, 44, -117, -87, 65, 13, 30, -87, 65, 35, -96, -89, 65, -87, -21, -91, 65, 77, -92, -92
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] buffer = new byte[4];
            ArrayList<String> list = new ArrayList<>();
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                // 处理读取的字节数据
                int l;
                l = buffer[0];
                l &= 0xff;
                l |= ((long) buffer[1] << 8);
                l &= 0xffff;
                l |= ((long) buffer[2] << 16);
                l &= 0xffffff;
                l |= ((long) buffer[3] << 24);
                String tempData = Float.intBitsToFloat(l) + "";
                String number = String.format("%.2f", Double.parseDouble(tempData));
                list.add(number);
            }

            BufferedWriter bw = new BufferedWriter(new FileWriter(desPath));
            for (int i = 0; i < list.size(); i++) {
                String s = list.get(i);
                bw.write(s);
                bw.write(",");
                int j = i + 1;
                if (j % width == 0){
                    bw.newLine();
                }
            }
            bw.close();
            return desPath;
//            for (int i = 0; i < 512; i++) {
//                for (int j = 0; j < 640; j++) {
//                    int index = j + i*640;
//                    String s = list.get(index);
//                    System.out.println("s" + s);
//                    bw.write(s);
//                    bw.write(",");
//                }
//                bw.newLine();
//            }

        } catch (IOException e) {
            e.printStackTrace();

        }
        return null;
    }


    // 根据json文件以及区域获取最大值
    public static Double getJsonHeightTemp(String path, int x, int y, int width, int height){
        File file = new File(path);
        try {
            FileReader fileReader = new FileReader(file);
            BufferedReader reader = new BufferedReader(fileReader);
            String line;
            ArrayList<String[]> list = new ArrayList<>();
            while ((line = reader.readLine()) != null){
//            System.out.println("line--" + line);
                String[] split = line.split(",");
//                System.out.println("split--" + Arrays.toString(split));
                list.add(split);
            }
            reader.close();
            fileReader.close();
            // 0 0 2 2
            ArrayList<Double> doubles = new ArrayList<Double>();
            for (int i = y; i < 512; i++) {
                if (i > y + width){
                    continue;
                }
                for (int j = x; j < 640; j++) {
                    if (j > x + height){
                        continue;
                    }
                    String[] strings = list.get(j);
                    String s = strings[i];
                    String number = String.format("%.2f", Double.parseDouble(s));
//                    System.out.println("x:" + j + ",y:" + i + ",温度值:" + number);
                    doubles.add(Double.parseDouble(number));
                }
            }
            Double max = Collections.max(doubles);
//            System.out.println("max--" + max);
            return max;
        }catch (Exception e){

        }
        return -1.0;
    }

}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值