因为工作需要,需要调用海康威视摄像头接口抓取Jpeg图片并保存到内存中,查找相关资料并整合,加上自己对官方提供的SDK文档,相关调用代码如下:
public class TestHikvision {
public static void main(String[] args) throws IOException {
TestHikvision app = new TestHikvision();
MonitorCameraInfo cameraInfo = new MonitorCameraInfo();//需要新建MonitorCameraInfo类
cameraInfo.setCameraIp("****");
cameraInfo.setCameraPort(8000);
cameraInfo.setUserName("admin");
cameraInfo.setUserPwd("****");
app.getDVRConfig(cameraInfo);
app.getDVRPic(cameraInfo);
//app.Test_CaptureJpegPicture_new(cameraInfo);
}
public void getDVRConfig(MonitorCameraInfo cameraInfo) {
HCNetSDK sdk = HCNetSDK.INSTANCE;
//判断摄像头是否开启
if (!sdk.NET_DVR_Init()) {
System.out.println("SDK初始化失败");
return;
}
//设置连接时间与重连
//sdk.NET_DVR_SetConnectTime(2000, 1);
//sdk.NET_DVR_SetReconnect(10000, true);
NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息
//System.out.println("设备信息:"+devinfo);
//登录信息
NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(),
cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo);
cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo
//输出int数据
//System.out.println("intValue:"+cameraInfo.getUserId().intValue());
if (cameraInfo.getUserId().intValue() < 0) {
System.out.println("设备注册失败");
return;
}
//DVR工作状态
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();//IP接入配置结构
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未知
//System.out.println("ChanNum"+devinfo.byChanNum);
// 显示模拟通道
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资源
sdk.NET_DVR_Cleanup();
}
//抓拍图片
public void getDVRPic(MonitorCameraInfo cameraInfo) throws IOException {
//设置通道号,其中1正常,-1不正常
NativeLong chanLong = new NativeLong(1);
cameraInfo.setChannel(chanLong);
//System.out.println("Channel:"+chanLong);
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();// 设备信息
//注册设备
NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(),
cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo);
cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo
if (cameraInfo.getUserId().intValue() < 0) {
System.out.println("设备注册失败"+sdk.NET_DVR_GetLastError());
return;
} else {
System.out.println("id:" + 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);
// 创建文件目录,文件?????
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = new Date();
String fileNameString = "D:/CapturePicture/"+sdf.format(date)+".jpg";
//还需要设置抓拍图片格式
/* String pathString = cameraInfo.getFilePath();*/
File file = new File(fileNameString);
/* if (!file.exists()) {
file.mkdirs(); //创建目录
}*/
//file.mkdirs();
// 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
//需要加入通道
boolean is = sdk.NET_DVR_CaptureJPEGPicture_NEW(cameraInfo.getUserId(), cameraInfo.getChannel(), jpeg,
jpegBuffer, 1024 * 1024, a);
//System.out.println("Channel:"+cameraInfo.getChannel());
System.out.println("抓图到内存耗时:[" + (System.currentTimeMillis() - startTime) + "ms]");
// 抓图到文件
//boolean is = sdk.NET_DVR_CaptureJPEGPicture(cameraInfo.UserId,cameraInfo.Channel,jpeg, fileNameString);
if (is) {
System.out.println("抓取成功,返回长度:" + a.getValue());
} else {
System.out.println("抓取失败:"+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();
}
}
代码参考了http://blog.csdn.net/redfoxtao/article/details/78080861
不同的地方在Net_DVR_CaptureJPEGPicture中调用的channel(通道号)直接设置值为1,已经去掉了file.mkdirs()。
大致就是这样,有问题的可以留言。