提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
java对接海康威视SDk实现红外DL/T抓图。
一、要获取的图片样式
二、实现步骤
1.导入海康威视的SDK
从海康威视官网根据操作系统下载对应的SDK和相关文件。
https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10
2.文件导入
在项目中导入如下文件。
3.代码实现
(1) main方法
package Test1;
import java.io.UnsupportedEncodingException;
import Test1.GeneralFunction.*;
import Test1.Thermometry.*;
import org.json.JSONException;
/**
*
*/
public class Test1 {
static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
public static int lUserID = -1;//用户句柄
static int dwState = -1; //人员信息状态
static int dwFaceState = -1; //下发人脸数据状态
static int iCharEncodeType = 0;//设备字符集
/**
* @param args
* @throws UnsupportedEncodingException
* @throws InterruptedException
* @throws JSONException
*/
public static void main(String[] args) throws UnsupportedEncodingException, InterruptedException, JSONException {
/*初始SDK*/
hCNetSDK.NET_DVR_Init();
//SDK日志
hCNetSDK.NET_DVR_SetLogToFile(3, "C:/JavaDemoLog", true);
/*登陆*/
Login login = new Login();
/*设备ip,端口,用户名,密码*/
lUserID = login.getlUserID("设备ip",(short)8000,"用户名","密码");
/*DL/T抓图*/
P2PRealData p2PRealData = new P2PRealData();
p2PRealData.getData(lUserID,2);
/*推出登录*/
if(hCNetSDK.NET_DVR_Logout(lUserID)){
System.out.println("登出成功!!!");
}
}
}
(2) SDK登录方法
package Test1.GeneralFunction;
import Test1.HCNetSDK;
/**
* 登录
*/
public class Login {
static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
public static int lUserID;//用户句柄
public int getlUserID(String m_sDeviceIP,short wPort,String m_sUsername,String m_sPassword){
//注册
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
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 = wPort;
m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
m_strLoginInfo.write();
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID == -1) {
System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
return -1;
} else {
System.out.println("登录成功!");
return lUserID;
}
}
}
(3) 抓图方法类
package Test1.Thermometry;
import Test1.HCNetSDK;
import Test1.PlayCtrl;
import com.sun.jna.ptr.NativeLongByReference;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Scanner;
/**
* Created by panting6 on 2021/2/21.
*/
public class P2PRealData {
static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
static PlayCtrl playControl = PlayCtrl.INSTANCE;
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
String newName = sf.format(new Date());
NativeLongByReference m_lPort;//回调预览时播放库端口指针
int lRealPlayHandle;
/**
* 获取数据,控制台输入控制是否结束测温并写入数据
*
* @param lUserID 用户登录句柄
* @throws InterruptedException
*/
public void getData(int lUserID,int iChannelNum) throws InterruptedException {
p2PRealData(lUserID, iChannelNum);
Scanner input = new Scanner(System.in);
}
/**
* DL/T抓图
*
* @param lUserID 用户登录句柄
* @param iChannelNum 通道号
* @throws InterruptedException
*/
public void p2PRealData(int lUserID, int iChannelNum) throws InterruptedException {
String s = "";
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
String newName = sf.format(date);
SimpleDateFormat sfz = new SimpleDateFormat("yyyy");
String year = sfz.format(date);
String strURL = "POST /ISAPI/Thermal/channels/2/thermometry/jpegPicWithAppendData?format=json";
HCNetSDK.BYTE_ARRAY ptrUrl = new HCNetSDK.BYTE_ARRAY(1024);
System.arraycopy(strURL.getBytes(), 0, ptrUrl.byValue, 0, strURL.length());
ptrUrl.write();
HCNetSDK.BYTE_ARRAY ptrInBuffer = new HCNetSDK.BYTE_ARRAY(1024 * 1024 * 10);
ptrInBuffer.read();
String strInbuffer = "{\n" +
"\t\"JpegPicWithAppendDataParam\":\n" +
"\t{\n" +
"\t\t\"captureMode\":\"standard\"\n" +
"\t}\n" +
"}\n";
ptrInBuffer.byValue = strInbuffer.getBytes();
ptrInBuffer.write();
HCNetSDK.NET_DVR_XML_CONFIG_INPUT net_dvr_xml_config_input = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT();
net_dvr_xml_config_input.read();
net_dvr_xml_config_input.dwSize = net_dvr_xml_config_input.size();
net_dvr_xml_config_input.lpRequestUrl = ptrUrl.getPointer();
net_dvr_xml_config_input.dwRequestUrlLen = ptrUrl.byValue.length;
net_dvr_xml_config_input.lpInBuffer = ptrInBuffer.getPointer();
net_dvr_xml_config_input.dwInBufferSize = ptrInBuffer.byValue.length;
net_dvr_xml_config_input.write();
//输出参数设置
HCNetSDK.BYTE_ARRAY ptrOutByte = new HCNetSDK.BYTE_ARRAY(1024 * 1024 * 10);
ptrOutByte.read();
HCNetSDK.BYTE_ARRAY ptrStatusByte = new HCNetSDK.BYTE_ARRAY(1024 * 1024 * 10);
ptrStatusByte.read();
HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT net_dvr_xml_config_output = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();
net_dvr_xml_config_output.read();
net_dvr_xml_config_output.dwSize = net_dvr_xml_config_output.size();
net_dvr_xml_config_output.lpOutBuffer = ptrOutByte.getPointer();
net_dvr_xml_config_output.dwOutBufferSize = ptrOutByte.size();
net_dvr_xml_config_output.write();
if (!hCNetSDK.NET_DVR_STDXMLConfig(lUserID, net_dvr_xml_config_input, net_dvr_xml_config_output)) {
System.out.println("信息获取失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
} else {
net_dvr_xml_config_output.read();
System.out.println("获取数据");
FileOutputStream fout;
//rectangle.setTime(newName);
try {
String filename = ".\\pic\\55\\";
//判断路径是否存在
File filePath = new File(filename);
if (!filePath.exists()) {
//不存在,创建目录
filePath.mkdirs();
}
filename = filename + newName + "PLAY_CELLPHONE_" + ".txt";
fout = new FileOutputStream(filename);
//将字节写入文件
long offset = 0;
ByteBuffer buffers = net_dvr_xml_config_output.lpOutBuffer.getByteBuffer(offset, net_dvr_xml_config_output.dwReturnedXMLSize);
byte[] bytes = new byte[net_dvr_xml_config_output.dwReturnedXMLSize];
buffers.rewind();
buffers.get(bytes);
//字符串截取
String indexStr = "Content-Length:";
String str = new String(bytes, StandardCharsets.UTF_8);//定义一个字符串
int index = str.indexOf(indexStr);
/**
* 去掉以下部分
* HTTP/1.1 200 OK
* MIME-Version: 1.0
* Content-Type: multipart/form-data; boundary=boundary
*
* --boundary
* Content-Type: application/json; charset="UTF-8"
* Content-Length:
*/
System.arraycopy(bytes, index + indexStr.length(), bytes, 0, net_dvr_xml_config_output.dwReturnedXMLSize - (index + indexStr.length()));
String str1 = new String(bytes, StandardCharsets.UTF_8);//定义一个字符串
int index2 = str1.indexOf(indexStr);
/**
* 去掉以下部分
* 131
*
* {
* "JpegPictureWithAppendDataResult": {
* "channel": 2,
* "appendDataVersion": "DL/T 664-2016",
* "appendDataDataLen": 1459158
* }
* }
* --boundary
* Content-Disposition: form-data;
* Content-Type: application/octet-stream
* Content-Length:
*/
System.arraycopy(bytes, index2 + indexStr.length(), bytes, 0, net_dvr_xml_config_output.dwReturnedXMLSize - (index2 + indexStr.length()));
String str2 = new String(bytes, StandardCharsets.UTF_8);
String s1 = "\r\n\r\n";
int index3 = str2.indexOf("\r\n\r\n");
/**
* 去掉
* 1459158
*
*/
System.arraycopy(bytes, index3 + s1.length(), bytes, 0, net_dvr_xml_config_output.dwReturnedXMLSize - (index3 + s1.length()));
if (bytes != null) {
s = "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(bytes);
}
fout.write(s.getBytes());
//关流
fout.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
总结
注意
在jna包的使用最好使用SDK提供的jna包,否则会报如下异常
Caused by: java.lang.Error: Structure.getFieldOrder() on class cn.zrpower.media.server.lib.HCNetSDK$NET_DVR_SDKSTATE does not provide enough names [0] ([]) to match declared fields [12] ([dwRes, dwTotalAlarmChanNum, dwTotalBroadCastNum, dwTotalFileSearchNum, dwTotalFormatNum, dwTotalLogSearchNum, dwTotalLoginNum, dwTotalPlayBackNum, dwTotalRealPlayNum, dwTotalSerialNum, dwTotalUpgradeNum, dwTotalVoiceComNum])
其他处理方法也可以重写SDK中对应的异常方法例如
public static class NET_DVR_STREAM_RECORD_STATUS extends Structure {
public int dwSize;
public byte byRecord;
public byte byOffLineRecord;
public byte[] byRes1 = new byte[2];
public int dwRelatedHD;
public byte[] byRes2 = new byte[8];
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("dwSize","byRecord","byOffLineRecord","byRes1","dwRelatedHD","byRes2");
}
}
本文含有隐藏内容,请 开通VIP 后查看