package com.netsdk.demo.customize; import java.util.Date; import java.io.File; import java.text.SimpleDateFormat; import com.netsdk.demo.util.CaseMenu; import com.netsdk.demo.util.Testable; import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.NetSDKLib.LLong; import com.netsdk.lib.ToolKits; import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; /** * 适用于 IPC, 球机等非智能交通、停车场设备 * 包括同步抓图和异步抓图 * @author 29779 * */ public class SnapPicture implements Testable { static NetSDKLib netsdkApi = NetSDKLib.NETSDK_INSTANCE; static NetSDKLib configApi = NetSDKLib.CONFIG_INSTANCE; private LLong loginHandle; private static class DisconnectCallback implements NetSDKLib.fDisConnect { private static DisconnectCallback instance = new DisconnectCallback(); private DisconnectCallback() {} public static DisconnectCallback getInstance() { return instance; } public void invoke(LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser){ System.out.printf("Device[%s:%d] Disconnect!\n" , pchDVRIP , nDVRPort); } } private static class HaveReconnectCallback implements NetSDKLib.fHaveReConnect { private static HaveReconnectCallback instance = new HaveReconnectCallback(); private HaveReconnectCallback() {} public static HaveReconnectCallback getInstance() { return instance; } public void invoke(LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser){ System.out.printf("Device[%s:%d] HaveReconnected!\n" , pchDVRIP , nDVRPort); } } @Override public void initTest() { //初始化SDK库 netsdkApi.CLIENT_Init(DisconnectCallback.getInstance(), null); //设置断线自动重练功能 netsdkApi.CLIENT_SetAutoReconnect(HaveReconnectCallback.getInstance(), null); // 向设备登入 final int nSpecCap = 0; /// login device by TCP final IntByReference error = new IntByReference(); final String address = "172.23.1.224"; final int port = 37777; final String usrname = "admin"; final String password = "admin"; final NetSDKLib.NET_DEVICEINFO deviceInfo = new NetSDKLib.NET_DEVICEINFO(); loginHandle = netsdkApi.CLIENT_LoginEx(address, (short)port, usrname, password, nSpecCap, null, deviceInfo, error); if(loginHandle.longValue() == 0) { System.err.printf("Login Device [%s:%d] Failed ! Last Error[%x]\n", address, port, netsdkApi.CLIENT_GetLastError()); return; } System.out.printf("Login Device [%s:%d] Success. \n", address, port); } public static class SnapCallback implements NetSDKLib.fSnapRev { private static SnapCallback instance = new SnapCallback(); private SnapCallback() {} public static SnapCallback getInstance() { return instance; } public void invoke( LLong lLoginID, Pointer pBuf, int RevLen, int EncodeType, int CmdSerial, Pointer dwUser) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyMMddHHmmss"); String fileName = "AsyncSnapPicture_" + dateFormat.format(new Date()) + "_" + CmdSerial + ".jpg"; //保存图片到本地文件 ToolKits.savePicture(pBuf, RevLen, fileName); System.out.println("--> Get Picture " + new File(fileName).getAbsolutePath()); // 成功生成图片之后, 进行通知 synchronized (SnapCallback.class) { SnapCallback.class.notify(); } } } /** * 异步方式抓图 :适用于 IPC, 球机等非智能交通、停车场设备 * 建议抓拍的频率不要超过1s */ public synchronized void asyncSnapPicture() { if (loginHandle.longValue() == 0) { return; } /// 设置抓图回调: 图片主要在 SnapCallback.getInstance() invoke. 中返回 netsdkApi.CLIENT_SetSnapRevCallBack(SnapCallback.getInstance(), null); NetSDKLib.SNAP_PARAMS snapParam = new NetSDKLib.SNAP_PARAMS(); snapParam.Channel = 0; //抓图通道 snapParam.mode = 0; //表示请求一帧 snapParam.CmdSerial = serialNum ++; // 请求序列号,有效值范围 0~65535,超过范围会被截断 /// 触发抓图动作 if (!netsdkApi.CLIENT_SnapPictureEx(loginHandle, snapParam , null)) { System.err.printf("CLIENT_SnapPictureEx Failed ! Last Error[%x]\n", netsdkApi.CLIENT_GetLastError()); return; } // 以下保证图片数据的生成 try { synchronized (SnapCallback.class) { SnapCallback.class.wait(3000L); // 默认等待3s, 防止设备断线时抓拍回调没有被触发,而导致死等 } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("--> " + Thread.currentThread().getName() + " CLIENT_SnapPictureEx Success." + System.currentTimeMillis()); } private int serialNum = 1; public void multiSnapPicture() { Thread[] threads = new Thread[5]; for (Thread thread : threads) { thread = new Thread(new Runnable() { @Override public void run() { asyncSnapPicture(); } }); thread.start(); } } /** * 同步方式抓图 , 建议抓拍的频率不要超过1s */ public void syncSnapPicture() { NetSDKLib.NET_IN_SNAP_PIC_TO_FILE_PARAM snapParamIn = new NetSDKLib.NET_IN_SNAP_PIC_TO_FILE_PARAM(); NetSDKLib.NET_OUT_SNAP_PIC_TO_FILE_PARAM snapParamOut = new NetSDKLib.NET_OUT_SNAP_PIC_TO_FILE_PARAM(1024 * 1024); snapParamIn.stuParam.Channel = 0; snapParamIn.stuParam.Quality = 3; snapParamIn.stuParam.ImageSize = 1; // 0:QCIF,1:CIF,2:D1 snapParamIn.stuParam.mode = 0; // -1:表示停止抓图, 0:表示请求一帧, 1:表示定时发送请求, 2:表示连续请求 snapParamIn.stuParam.InterSnap = 5; snapParamIn.stuParam.CmdSerial = serialNum; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyMMddHHmmss"); final String fileName = "SyncSnapPicture_" + dateFormat.format(new Date()) + "_" + serialNum + ".jpg"; System.arraycopy(fileName.getBytes(), 0, snapParamIn.szFilePath, 0, fileName.getBytes().length); final int timeOut = 5000; // 5 second Pointer pInbuf =new Memory(snapParamIn.size()); ToolKits.SetStructDataToPointer(snapParamIn, pInbuf, 0); Pointer pOutbuf =new Memory(snapParamOut.size()); ToolKits.SetStructDataToPointer(snapParamOut, pOutbuf, 0); if (!netsdkApi.CLIENT_SnapPictureToFile(loginHandle, pInbuf, pOutbuf, timeOut)) { System.err.printf("CLIENT_SnapPictureEx Failed ! Last Error[%x]\n", netsdkApi.CLIENT_GetLastError()); return; } ToolKits.GetPointerData(pOutbuf,snapParamOut); Pointer szPicBuf = snapParamOut.szPicBuf; byte[] byteArray = szPicBuf.getByteArray(0, snapParamOut.dwPicBufRetLen); System.out.println("CLIENT_SnapPictureToFile Success. " + new File(fileName).getAbsolutePath()); // 图片下载完之后回收指针 Native.free(Pointer.nativeValue(szPicBuf)); Native.free(Pointer.nativeValue(pInbuf)); Native.free(Pointer.nativeValue(pOutbuf)); } @Override public void runTest() { System.out.println("Run Test"); CaseMenu menu = new CaseMenu(); menu.addItem(new CaseMenu.Item(this, "Async Snap picture.", "asyncSnapPicture")); menu.addItem(new CaseMenu.Item(this, "Mutil Snap picture.", "multiSnapPicture")); menu.addItem(new CaseMenu.Item(this, "Sync Snap picture.", "syncSnapPicture")); menu.run(); } @Override public void endTest() { if( loginHandle.longValue() != 0) { netsdkApi.CLIENT_Logout(loginHandle); loginHandle.setValue(0); } /// 清理资源, 只需调用一次 netsdkApi.CLIENT_Cleanup(); System.out.println("See You..."); } public static void main(String[] args) { SnapPicture demo = new SnapPicture(); demo.initTest(); demo.runTest(); demo.endTest(); } }