package com.netsdk.demo.customize;
|
|
import com.netsdk.demo.util.CaseMenu;
|
import com.netsdk.lib.NetSDKLib;
|
import com.netsdk.lib.NetSDKLib.*;
|
import com.netsdk.lib.ToolKits;
|
import com.netsdk.lib.enumeration.NET_EM_CFG_OPERATE_TYPE;
|
import com.sun.jna.Memory;
|
import com.sun.jna.Pointer;
|
import com.sun.jna.ptr.IntByReference;
|
|
import java.io.File;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
|
public class SDSnap {
|
|
/*static{
|
System.setProperty("java.io.tmpdir", "D:/");
|
}*/
|
static NetSDKLib netSdk = NetSDKLib.NETSDK_INSTANCE;
|
|
// 设备信息
|
private NetSDKLib.NET_DEVICEINFO_Ex deviceinfo = new NetSDKLib.NET_DEVICEINFO_Ex();
|
|
//登陆句柄
|
private LLong loginHandle = new LLong(0);
|
|
// 智能订阅句柄
|
private LLong attachHandle = new LLong(0);
|
|
|
/**
|
* 通用服务
|
*/
|
static class SDKGeneralService {
|
|
// 网络断线回调
|
// 调用 CLIENT_Init设置此回调, 当设备断线时会自动调用.
|
public static class DisConnect implements NetSDKLib.fDisConnect{
|
|
private DisConnect() {}
|
|
private static class CallBackHolder {
|
private static final DisConnect cb = new DisConnect();
|
}
|
|
public static final DisConnect getInstance() {
|
return CallBackHolder.cb;
|
}
|
|
public void invoke(LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
|
System.out.printf("Device[%s] Port[%d] Disconnect!\n" , pchDVRIP , nDVRPort);
|
}
|
}
|
|
// 网络连接恢复回调
|
// 调用 CLIENT_SetAutoReconnect设置此回调, 当设备重连时会自动调用.
|
public static class HaveReConnect implements NetSDKLib.fHaveReConnect{
|
|
private HaveReConnect() {}
|
|
private static class CallBackHolder {
|
private static final HaveReConnect cb = new HaveReConnect();
|
}
|
|
public static final HaveReConnect getInstance() {
|
return CallBackHolder.cb;
|
}
|
|
public void invoke(LLong loginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
|
System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);
|
}
|
}
|
|
/**
|
* SDK初始化
|
*/
|
public static void init()
|
{
|
// SDK资源初始化
|
netSdk.CLIENT_Init(DisConnect.getInstance(), null);
|
|
// 设置断线重连回调,当设备断线后会自动重连并在重连后自动调用HaveReConnect(可选)
|
netSdk.CLIENT_SetAutoReconnect(HaveReConnect.getInstance(), null);
|
|
// 打开SDK日志(可选)
|
LOG_SET_PRINT_INFO setLog = new LOG_SET_PRINT_INFO();
|
String logPath = new File(".").getAbsoluteFile().getParent() + File.separator + "sdk_log" + File.separator + "sdk.log";
|
setLog.bSetFilePath = 1;
|
System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
|
|
setLog.bSetPrintStrategy = 1;
|
setLog.nPrintStrategy = 0;
|
boolean bLogopen = netSdk.CLIENT_LogOpen(setLog);
|
if (!bLogopen) {
|
System.err.println("Failed to open NetSDK log !!!");
|
}
|
|
netSdk.CLIENT_SetSnapRevCallBack(SnapCallback.getInstance(), null);
|
}
|
|
/**
|
* SDK反初始化——释放资源
|
*/
|
public static void cleanup() {
|
netSdk.CLIENT_Cleanup();
|
}
|
}
|
|
/**
|
* 登陆设备
|
*/
|
public boolean login() {
|
|
int nSpecCap = 0;
|
Pointer pCapParam = null;
|
IntByReference nError = new IntByReference(0);
|
loginHandle = netSdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser,
|
m_strPassword, nSpecCap, pCapParam, deviceinfo, nError);
|
|
if(loginHandle.longValue() != 0) {
|
System.out.printf("Login Device[%s] Port[%d] Success!\n" , m_strIp , m_nPort);
|
} else {
|
System.out.printf("Login Device[%s] Port[%d] Failed. %s\n" , m_strIp , m_nPort , ToolKits.getErrorCode());
|
}
|
|
return loginHandle.longValue() != 0;
|
}
|
|
|
|
/**
|
* 登出设备
|
*/
|
public void logout() {
|
if(loginHandle.longValue() != 0){
|
netSdk.CLIENT_Logout(loginHandle);
|
}
|
}
|
|
public void InitTest() {
|
SDKGeneralService.init(); // SDK初始化
|
if (!login()) { // 登陆设备
|
EndTest();
|
}
|
}
|
|
public void EndTest() {
|
stopLoadPicture(); // 取消订阅
|
logout(); // 登出设备
|
System.out.println("See You...");
|
SDKGeneralService.cleanup(); // 反初始化
|
System.exit(0);
|
}
|
|
/**
|
* 远程抓图(异步)
|
*/
|
public void snapPicture() {
|
// send caputre picture command to device
|
NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS();
|
stuSnapParams.Channel = 0; // channel
|
stuSnapParams.mode = 0; // capture picture mode
|
stuSnapParams.Quality = 3; // picture quality
|
stuSnapParams.InterSnap = 0;
|
stuSnapParams.CmdSerial = 0;
|
|
IntByReference reserved = new IntByReference(0);
|
if (!netSdk.CLIENT_SnapPictureEx(loginHandle, stuSnapParams, reserved)) {
|
System.err.printf("CLIENT_SnapPictureEx Failed!" + ToolKits.getErrorCode());
|
} else {
|
System.out.println("CLIENT_SnapPictureEx success");
|
}
|
}
|
|
public static class SnapCallback implements NetSDKLib.fSnapRev {
|
private static SnapCallback instance = new SnapCallback();
|
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyMMddHHmmss");
|
private File path;
|
|
private SnapCallback() {
|
path = new File("./Snap/");
|
if (!path.exists()) {
|
path.mkdir();
|
}
|
}
|
|
public static SnapCallback getInstance() {
|
return instance;
|
}
|
|
public void invoke( LLong lLoginID, Pointer pBuf, int RevLen, int EncodeType, int CmdSerial, Pointer dwUser) {
|
if (EncodeType == 10) { // jpg
|
String fileName = path + File.separator + "AsyncSnapPicture_" + dateFormat.format(new Date()) + ".jpg";
|
//保存图片到本地文件
|
ToolKits.savePicture(pBuf, RevLen, fileName);
|
}
|
}
|
}
|
|
/**
|
* 智能报警事件回调
|
*/
|
public static class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack{
|
|
private NetSDKLib.DEV_EVENT_TRAFFIC_PARKING_INFO msg;
|
private File path;
|
private AnalyzerDataCB() {
|
msg = new NetSDKLib.DEV_EVENT_TRAFFIC_PARKING_INFO();
|
path = new File("./Snap/");
|
if (!path.exists()) {
|
path.mkdir();
|
}
|
}
|
|
private static class CallBackHolder {
|
private static AnalyzerDataCB instance = new AnalyzerDataCB();
|
}
|
|
public static AnalyzerDataCB getInstance() {
|
return CallBackHolder.instance;
|
}
|
|
// 回调
|
public int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType, Pointer pAlarmInfo,
|
Pointer pBuffer, int dwBufSize, Pointer dwUser, int nSequence, Pointer reserved)
|
{
|
if (lAnalyzerHandle == null || lAnalyzerHandle.longValue() == 0) {
|
return -1;
|
}
|
|
switch (dwAlarmType) {
|
//case NetSDKLib.EVENT_IVS_TRAFFIC_MANUALSNAP: // 交通手动抓拍事件
|
case NetSDKLib.EVENT_IVS_TRAFFIC_PARKING_MANUAL://
|
{
|
dealData(pAlarmInfo, pBuffer, dwBufSize);
|
break;
|
}
|
default:
|
break;
|
}
|
|
return 0;
|
}
|
|
/**
|
* 处理事件
|
*/
|
private void dealData(Pointer pAlarmInfo, Pointer pImageBuffer, int nBufferSize) {
|
ToolKits.GetPointerData(pAlarmInfo, msg);
|
System.out.printf("UTC[%s] 车牌[%s] 事件对应文件信息[当前文件所在文件组中的文件总数:%d 编号:%d 文件类型:%d 唯一标识:%d] \n",
|
msg.UTC.toStringTime(), new String(msg.stuObject.szText).trim(),
|
msg.stuFileInfo.bCount, msg.stuFileInfo.bIndex, msg.stuFileInfo.bFileType, msg.stuFileInfo.nGroupId);
|
|
// 保存大图
|
String bigPicture = path + File.separator + String.format("BigPicture_%s_%d_%d_%d_%d.jpg",
|
msg.stuFileInfo.stuFileTime.toStringTitle(),
|
msg.stuFileInfo.bCount, msg.stuFileInfo.bIndex, msg.stuFileInfo.bFileType, msg.stuFileInfo.nGroupId);
|
ToolKits.savePicture(pImageBuffer, 0, nBufferSize, bigPicture);
|
/*byte[] buffer = pImageBuffer.getByteArray(0, nBufferSize);
|
BufferedImage bigImage = null;
|
try {
|
bigImage = ImageIO.read(new ByteArrayInputStream(buffer));
|
ImageIO.write(bigImage, "jpg", new File(bigPicture));
|
} catch (IOException e1) {
|
e1.printStackTrace();
|
}*/
|
// 保存车牌图片
|
String platePicture = path + File.separator + String.format("PlatePicture_%s_%d_%d_%d_%d.jpg",
|
msg.stuFileInfo.stuFileTime.toStringTitle(),
|
msg.stuFileInfo.bCount, msg.stuFileInfo.bIndex, msg.stuFileInfo.bFileType, msg.stuFileInfo.nGroupId);
|
NET_PIC_INFO stPicInfo = msg.stuObject.stPicInfo;
|
if (stPicInfo.dwFileLenth > 0) {
|
ToolKits.savePicture(pImageBuffer, stPicInfo.dwOffSet, stPicInfo.dwFileLenth, platePicture);
|
}/*else if (bigImage != null){
|
NetSDKLib.DH_RECT boundingBox = msg.stuObject.BoundingBox;
|
long nWidth = bigImage.getWidth(null);
|
long nHeight = bigImage.getHeight(null);
|
int x = (int) ((nWidth * boundingBox.left.longValue()) / 8192.0);
|
int y = (int) ((nHeight * boundingBox.top.longValue()) / 8192.0);
|
int w = (int) ((nWidth * boundingBox.right.longValue()) / 8192.0) - x;
|
int h = (int) ((nHeight * boundingBox.bottom.longValue()) / 8192.0) - y;
|
if (w <= 0 || h <= 0) {
|
System.err.println("无车牌信息");
|
return;
|
}
|
try {
|
ImageIO.write(bigImage.getSubimage(x, y, w, h), "jpg", new File(platePicture));
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}*/
|
|
|
}
|
}
|
|
/**
|
* 智能订阅
|
*/
|
public boolean realLoadPicture() {
|
int bNeedPicture = 1; // 是否需要图片
|
int channel = -1; // 订阅全通道
|
if (deviceinfo.byChanNum == 1) {
|
channel = 0;
|
}
|
attachHandle = netSdk.CLIENT_RealLoadPictureEx(loginHandle, channel,
|
NetSDKLib.EVENT_IVS_ALL, bNeedPicture, AnalyzerDataCB.getInstance(), null , null);
|
if (attachHandle.longValue() != 0) {
|
System.out.printf("Channel[%d] RealLoad Picture Success!\n", channel);
|
}else {
|
System.err.printf("Channel[%d] RealLoad Picture Failed! %s\n", channel, ToolKits.getErrorCode());
|
}
|
|
return attachHandle.longValue() != 0;
|
}
|
|
/**
|
* 停止智能订阅
|
*/
|
public void stopLoadPicture() {
|
if (attachHandle.longValue() != 0) {
|
netSdk.CLIENT_StopLoadPic(attachHandle);
|
attachHandle.setValue(0);
|
System.out.println("Had Stop RealLoad Picture!");
|
}
|
}
|
|
/**
|
* 云台配置
|
*/
|
public void cfgPTZ()
|
{
|
CFG_PTZ_INFO stuPTZ = new CFG_PTZ_INFO();
|
if (!ToolKits.GetDevConfig(loginHandle, 0, NetSDKLib.CFG_CMD_PTZ, stuPTZ)) {
|
System.err.println("Get PTZ Failed!" + ToolKits.getErrorCode());
|
return;
|
}
|
|
System.out.printf("Enable: %d PresetId:%d FreeSec:%d \n", stuPTZ.bEnable,
|
stuPTZ.stuPresetHoming.nPtzPresetId, stuPTZ.stuPresetHoming.nFreeSec);
|
|
stuPTZ.bEnable = 1; // 使能
|
stuPTZ.stuPresetHoming.nFreeSec = 36; // 归位时间,单位为秒
|
if (!ToolKits.SetDevConfig(loginHandle, 0, NetSDKLib.CFG_CMD_PTZ, stuPTZ)) {
|
System.err.println("Set PTZ Failed!" + ToolKits.getErrorCode());
|
}else {
|
System.err.println("Set PTZ Success!");
|
}
|
}
|
|
// 选中目标进行抓拍
|
public void snapPictureByAnalyseObject() {
|
NET_IN_SNAP_BY_ANALYSE_OBJECT stuIn = new NET_IN_SNAP_BY_ANALYSE_OBJECT();
|
|
stuIn.nChannelID = 0; // 通道号
|
stuIn.nSnapObjectNum = 1; // 抓拍物体个数
|
// 抓拍物体信息 (点坐标归一化到[0, 8192]坐标)
|
// 实际使用时通过如下计算: 8192.0 * 相对坐标/显示宽(高) 其中左右通过显示的宽度计算,上下通过显示的高度计算
|
// 如 (int)(8192.0*80/120)——浮点计算是为了使结果更精确
|
// stuIn.stuSnapObjects[0].stuBoundingBox.left = 0;
|
// stuIn.stuSnapObjects[0].stuBoundingBox.top = 0;
|
// stuIn.stuSnapObjects[0].stuBoundingBox.right = 8192;
|
// stuIn.stuSnapObjects[0].stuBoundingBox.bottom = 8192;
|
stuIn.stuSnapObjects[0].stuBoundingBox.left = 4154;
|
stuIn.stuSnapObjects[0].stuBoundingBox.top = 3172;
|
stuIn.stuSnapObjects[0].stuBoundingBox.right = 5160;
|
stuIn.stuSnapObjects[0].stuBoundingBox.bottom = 4380;
|
|
NET_OUT_SNAP_BY_ANALYSE_OBJECT stuOut = new NET_OUT_SNAP_BY_ANALYSE_OBJECT();
|
if (!netSdk.CLIENT_SnapPictureByAnalyseObject(loginHandle, stuIn, stuOut, 5000)) {
|
System.err.println("Snap Picture By Analyse Object Failed!" + ToolKits.getErrorCode());
|
}else {
|
System.err.println("Snap Picture By Analyse Object Success!");
|
}
|
}
|
|
/**
|
* 场景抓拍设置
|
*/
|
public void snapShotWithRulecfg()
|
{
|
int nMaxRuleNum = 10; // 可根据实际修改
|
NetSDKLib.NET_SCENE_SNAP_SHOT_WITH_RULE2_INFO[] stuRule = new NetSDKLib.NET_SCENE_SNAP_SHOT_WITH_RULE2_INFO[nMaxRuleNum];
|
for (int i = 0; i < nMaxRuleNum; ++i) {
|
stuRule[i] = new NET_SCENE_SNAP_SHOT_WITH_RULE2_INFO();
|
}
|
|
int emCfgOpType = NET_EM_CFG_OPERATE_TYPE.NET_EM_CFG_SCENE_SNAP_SHOT_WITH_RULE2; // 场景抓拍设置
|
int nChannelID = 0;
|
NET_CFG_SCENE_SNAP_SHOT_WITH_RULE2_INFO stuCfg = new NET_CFG_SCENE_SNAP_SHOT_WITH_RULE2_INFO();
|
stuCfg.nMaxRuleNum = nMaxRuleNum;
|
stuCfg.pstuSceneSnapShotWithRule = new Memory(nMaxRuleNum * stuRule[0].size());
|
stuCfg.pstuSceneSnapShotWithRule.clear(nMaxRuleNum * stuRule[0].size());
|
ToolKits.SetStructArrToPointerData(stuRule, stuCfg.pstuSceneSnapShotWithRule);
|
|
// 获取
|
stuCfg.write();
|
if (!netSdk.CLIENT_GetConfig(loginHandle, emCfgOpType, nChannelID,
|
stuCfg.getPointer(), stuCfg.size(), 4000, null)) {
|
System.err.println("获取场景抓拍配置失败!" + ToolKits.getErrorCode());
|
return;
|
}
|
|
stuCfg.read();
|
ToolKits.GetPointerDataToStructArr(stuCfg.pstuSceneSnapShotWithRule, stuRule);
|
|
System.out.printf("stuRule[0]--PresetID:%d RuleNum:%d RuleType:%x SingleInterval:%d\n",
|
stuRule[0].nPresetID, stuRule[0].nRetSnapShotRuleNum,
|
stuRule[0].stuSnapShotWithRule[0].dwRuleType, stuRule[0].stuSnapShotWithRule[0].nSingleInterval[1]);
|
|
// 设置,在获取的基础上设置
|
IntByReference restart = new IntByReference(0);
|
stuRule[0].stuSnapShotWithRule[0].nSingleInterval[1] = 15; // 抓图时间间隔
|
ToolKits.SetStructArrToPointerData(stuRule, stuCfg.pstuSceneSnapShotWithRule);
|
stuCfg.write();
|
if (!netSdk.CLIENT_SetConfig(loginHandle, emCfgOpType, nChannelID,
|
stuCfg.getPointer(), stuCfg.size(), 4000, restart, null)) {
|
System.err.println("设置场景抓拍配置失败!" + ToolKits.getErrorCode());
|
} else {
|
System.err.println("设置场景抓拍配置成功!");
|
}
|
}
|
|
////////////////////////////////////////////////////////////////
|
private String m_strIp = "172.32.1.22";
|
private int m_nPort = 37777;
|
private String m_strUser = "admin";
|
private String m_strPassword = "admin123";
|
////////////////////////////////////////////////////////////////
|
|
public void RunTest()
|
{
|
System.out.println("Run Test");
|
CaseMenu menu = new CaseMenu();
|
menu.addItem(new CaseMenu.Item(this , "远程抓图" , "snapPicture"));
|
menu.addItem(new CaseMenu.Item(this , "智能订阅" , "realLoadPicture"));
|
menu.addItem(new CaseMenu.Item(this , "停止智能订阅" , "stopLoadPicture"));
|
menu.addItem(new CaseMenu.Item(this , "云台配置" , "cfgPTZ"));
|
menu.addItem(new CaseMenu.Item(this , "选中目标进行抓拍" , "snapPictureByAnalyseObject"));
|
menu.addItem(new CaseMenu.Item(this , "场景抓拍设置" , "snapShotWithRulecfg"));
|
|
menu.run();
|
}
|
|
public static void main(String[]args)
|
{
|
SDSnap demo = new SDSnap();
|
demo.InitTest();
|
demo.RunTest();
|
demo.EndTest();
|
}
|
}
|