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;
}
}
很无语的地方,读取ptz参数和转换
git代码已经修正。真无语