Java调用Hikvision接口并抓取Jpeg图片到内存
示例代码如下:
package cn.xaele.javacv.test.hikvision;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import cn.xaele.javacv.test.hikvision.HCNetSDK.NET_DVR_DEVICEINFO_V30;
import cn.xaele.javacv.test.hikvision.HCNetSDK.NET_DVR_IPPARACFG;
import cn.xaele.javacv.test.hikvision.HCNetSDK.NET_DVR_JPEGPARA;
import cn.xaele.javacv.test.hikvision.HCNetSDK.NET_DVR_WORKSTATE_V30;
public class TestHikvision {
public static void main(String[] args) {
TestHikvision app = new TestHikvision();
MonitorCameraInfo cameraInfo = new MonitorCameraInfo();
cameraInfo.setCameraIp("10.10.12.13");
cameraInfo.setCameraPort(8000);
cameraInfo.setUserName("admin");
cameraInfo.setUserPwd("12345");
app.getDVRConfig(cameraInfo);
app.getDVRPic(cameraInfo);
}
public void getDVRConfig(MonitorCameraInfo cameraInfo) {
HCNetSDK sdk = HCNetSDK.INSTANCE;
if (!sdk.NET_DVR_Init()) {
System.out.println("SDK初始化失败");
return;
}
NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息
cameraInfo.setUserId(sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(),
cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo));// 返回一个用户编号,同时将设备信息写入devinfo
if (cameraInfo.getUserId().intValue() < 0) {
System.out.println("设备注册失败");
return;
}
NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30();
if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) {
// 返回Boolean值,判断是否获取设备能力
System.out.println("返回设备状态失败");
}
IntByReference ibrBytesReturned = new IntByReference(0);// 获取IP接入配置参数
NET_DVR_IPPARACFG ipcfg = new NET_DVR_IPPARACFG();
ipcfg.write();
Pointer lpIpParaConfig = ipcfg.getPointer();
sdk.NET_DVR_GetDVRConfig(cameraInfo.getUserId(), HCNetSDK.NET_DVR_GET_IPPARACFG, new NativeLong(0),
lpIpParaConfig, ipcfg.size(), ibrBytesReturned);
ipcfg.read();
System.out.print("IP地址:" + cameraInfo.getCameraIp());
System.out.println("|设备状态:" + devwork.dwDeviceStatic);// 0正常,1CPU占用率过高,2硬件错误,3未知
// 显示模拟通道
for (int i = 0; i < devinfo.byChanNum; i++) {
System.out.print("Camera" + i + 1);// 模拟通道号名称
System.out.print("|是否录像:" + devwork.struChanStatic[i].byRecordStatic);// 0不录像,不录像
System.out.print("|信号状态:" + devwork.struChanStatic[i].bySignalStatic);// 0正常,1信号丢失
System.out.println("|硬件状态:" + devwork.struChanStatic[i].byHardwareStatic);// 0正常,1异常
}
sdk.NET_DVR_Logout(cameraInfo.getUserId());
sdk.NET_DVR_Cleanup();
}
public void getDVRPic(MonitorCameraInfo cameraInfo) {
long startTime = System.currentTimeMillis();
HCNetSDK sdk = HCNetSDK.INSTANCE;
if (!sdk.NET_DVR_Init()) {
System.out.println("SDK初始化失败");
return;
}
NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息
cameraInfo.setUserId(sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(),
cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo));// 返回一个用户编号,同时将设备信息写入devinfo
int Iuid = cameraInfo.getUserId().intValue();
if (Iuid < 0) {
System.out.println("设备注册失败");
return;
} else {
System.out.println("Iuid[" + cameraInfo.getUserId().intValue() + "]");
}
NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30();
if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) {
// 返回Boolean值,判断是否获取设备能力
System.out.println("返回设备状态失败");
}
System.out.println("设备注册耗时:[" + (System.currentTimeMillis() - startTime) + "]");
startTime = System.currentTimeMillis();
NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA();
// 设置图片的分辨率
jpeg.wPicSize = 2;
// 设置图片质量
jpeg.wPicQuality = 2;
IntByReference a = new IntByReference();
ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
// 创建文件目录
File file = new File(cameraInfo.getFilePath() + "/a.jpg");
file.mkdirs();
System.out.println("文件路径:[" + cameraInfo.getFilePath() + "/a.jpg" + "]");
// 抓图到内存
boolean is = sdk.NET_DVR_CaptureJPEGPicture_NEW(cameraInfo.getUserId(), cameraInfo.getChannel(), jpeg,
jpegBuffer, 1024 * 1024, a);
System.out.println("抓图到内存耗时:[" + (System.currentTimeMillis() - startTime) + "]");
// 抓图到文件
// boolean is = sdk.NET_DVR_CaptureJPEGPicture(cameraInfo.userId,
// cameraInfo.channel, jpeg, cameraInfo.getFilePath() + "/b.jpg");
if (is) {
System.out.println("抓取成功,返回长度:" + a.getValue());
} else {
System.out.println("抓取失败");
}
System.out.println(is + " " + sdk.NET_DVR_GetLastError());
startTime = System.currentTimeMillis();
// 存储本地
BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(file));
outputStream.write(jpegBuffer.array(), 0, a.getValue());
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("存储本地耗时:[" + (System.currentTimeMillis() - startTime) + "]");
sdk.NET_DVR_Logout(cameraInfo.getUserId());
sdk.NET_DVR_Cleanup();
}
}
注:HCNetSDK中需要更改如下(使用ByteBuffer替代海康提供接口中的String)
// JPEG抓图到内存
boolean NET_DVR_CaptureJPEGPicture_NEW(NativeLong lUserID, NativeLong lChannel, NET_DVR_JPEGPARA lpJpegPara,
ByteBuffer sJpegPicBuffer, int dwPicSize, IntByReference lpSizeReturned);