1
zhanghua
2024-09-26 c775c6953d9759e70f08acbfa8f6d7490aaae3d1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
package com.netsdk.demo.customize;
 
import static com.netsdk.lib.Utils.getOsPrefix;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Objects;
import java.util.Scanner;
 
 
import com.netsdk.demo.customize.faceReconEx.DefaultFaceFindStateCallback;
import com.netsdk.demo.util.CaseMenu;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.ToolKits;
import com.netsdk.lib.NetSDKLib.DEV_EVENT_HUMANTRAIT_INFO;
import com.netsdk.lib.NetSDKLib.LLong;
import com.netsdk.lib.NetSDKLib.NET_GET_CHANNEL_INFO;
import com.netsdk.lib.NetSDKLib.NET_GET_DEVICE_INFO;
import com.netsdk.lib.NetSDKLib.NET_IN_FACE_RECOGNITION_DEL_DISPOSITION_INFO;
import com.netsdk.lib.NetSDKLib.NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO;
import com.netsdk.lib.NetSDKLib.NET_IN_GET_CHANNEL_INFO;
import com.netsdk.lib.NetSDKLib.NET_IN_GET_DEVICE_LIST_INFO;
import com.netsdk.lib.NetSDKLib.NET_IN_OPERATE_FACERECONGNITIONDB;
import com.netsdk.lib.NetSDKLib.NET_OUT_FACE_RECOGNITION_DEL_DISPOSITION_INFO;
import com.netsdk.lib.NetSDKLib.NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO;
import com.netsdk.lib.NetSDKLib.NET_OUT_GET_CHANNEL_INFO;
import com.netsdk.lib.NetSDKLib.NET_OUT_GET_DEVICE_LIST_INFO;
import com.netsdk.lib.NetSDKLib.NET_OUT_OPERATE_FACERECONGNITIONDB;
import com.netsdk.lib.NetSDKLib.NET_TRAFFICCAR_BLACK_LIST;
import com.netsdk.lib.NetSDKLib.NET_UID_CHAR;
import com.netsdk.lib.NetSDKLib.SdkStructure;
import com.netsdk.lib.callback.impl.DefaultDisconnectCallback;
import com.netsdk.lib.callback.impl.DefaultHaveReconnectCallBack;
import com.netsdk.lib.enumeration.EM_DETECT_OBJECT_TYPE;
import com.netsdk.lib.enumeration.EM_EVENT_IVS_TYPE;
import com.netsdk.lib.enumeration.EM_MULTIFACE_DETECT_ERRCODE;
import com.netsdk.lib.enumeration.EM_NEEDED_PIC_RETURN_TYPE;
import com.netsdk.lib.enumeration.EM_OBJECT_COLOR_TYPE;
import com.netsdk.lib.enumeration.ENUMERROR;
import com.netsdk.lib.structure.NET_CANDIDATE_INFOEX2;
import com.netsdk.lib.structure.NET_CB_MULTIFACE_DETECT_STATE;
import com.netsdk.lib.structure.NET_DEVICE_CHANNEL_INFO;
import com.netsdk.lib.structure.NET_GET_DEVICE_INFO_EX;
import com.netsdk.lib.structure.NET_IN_DOFIND_FACERECONGNITION_EX;
import com.netsdk.lib.structure.NET_IN_FACERSERVER_GETDETEVTTOKEN;
import com.netsdk.lib.structure.NET_IN_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO;
import com.netsdk.lib.structure.NET_IN_GET_DEVICE_INFO_EX;
import com.netsdk.lib.structure.NET_IN_MULTIFACE_DETECT_STATE;
import com.netsdk.lib.structure.NET_IN_STARTMULTIFIND_FACERECONGNITION_EX;
import com.netsdk.lib.structure.NET_OUT_DOFIND_FACERECONGNITION_EX;
import com.netsdk.lib.structure.NET_OUT_FACERSERVER_GETDETEVTTOKEN;
import com.netsdk.lib.structure.NET_OUT_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO;
import com.netsdk.lib.structure.NET_OUT_GET_DEVICE_INFO_EX;
import com.netsdk.lib.structure.NET_OUT_MULTIFACE_DETECT_STATE;
import com.netsdk.lib.structure.NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX;
import com.netsdk.lib.structure.NET_SMALL_PIC_INFO;
import com.netsdk.module.AnalyseTaskModule;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
public class MC8000Demo {
    // SDk对象初始化
    public static final NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    public static final NetSDKLib configsdk = NetSDKLib.CONFIG_INSTANCE;
 
    // 判断是否初始化
    private static boolean bInit = false;
    // 判断log是否打开
    private static boolean bLogOpen = false;
    // 设备信息
    private NetSDKLib.NET_DEVICEINFO_Ex deviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
    // 登录句柄
    private NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0);
 
    // 智能事件订阅句柄
    private NetSDKLib.LLong m_attachHandle = new NetSDKLib.LLong(0);
 
    // 回调函数需要是静态的,防止被系统回收
    // 断线回调
    private static NetSDKLib.fDisConnect disConnectCB = DefaultDisconnectCallback.getINSTANCE();
    // 重连回调
    private static NetSDKLib.fHaveReConnect haveReConnectCB = DefaultHaveReconnectCallBack.getINSTANCE();
 
    // 编码格式
    public static String encode;
 
    static {
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32-amd64")) {
            encode = "GBK";
        } else if (osPrefix.toLowerCase().startsWith("linux-amd64")) {
            encode = "UTF-8";
        }
    }
 
    /**
     * 获取当前时间
     */
    public static String GetDate() {
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDate.format(new java.util.Date()).replaceAll("[^0-9]", "-");
    }
 
    /**
     * 初始化SDK库
     */
    public static boolean Init() {
        bInit = netsdk.CLIENT_Init(disConnectCB, null);// 进程启动时,初始化一次
        if (!bInit) {
            System.out.println("Initialize SDK failed");
            return false;
        }
        // 配置日志
        MC8000Demo.enableLog();
 
        // 设置断线重连回调接口, 此操作为可选操作,但建议用户进行设置
        netsdk.CLIENT_SetAutoReconnect(haveReConnectCB, null);
 
        // 设置登录超时时间和尝试次数,可选
        // 登录请求响应超时时间设置为3S
        int waitTime = 3000;
        // 登录时尝试建立链接 1 次
        int tryTimes = 1;
        netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);
        // 设置更多网络参数, NET_PARAM 的nWaittime , nConnectTryNum 成员与 CLIENT_SetConnectTime
        // 接口设置的登录设备超时时间和尝试次数意义相同,可选
        NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
        // 登录时尝试建立链接的超时时间
        netParam.nConnectTime = 10000;
        // 设置子连接的超时时间
        netParam.nGetConnInfoTime = 3000;
        netsdk.CLIENT_SetNetworkParam(netParam);
        return true;
    }
 
    /**
     * 打开 sdk log
     */
    private static void enableLog() {
        NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        File path = new File("sdklog/");
        if (!path.exists())
            path.mkdir();
 
        // 这里的log保存地址依据实际情况自己调整
        String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + "sdklog" + GetDate() + ".log";
        setLog.nPrintStrategy = 0;
        setLog.bSetFilePath = 1;
        System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        System.out.println(logPath);
        setLog.bSetPrintStrategy = 1;
        bLogOpen = netsdk.CLIENT_LogOpen(setLog);
        if (!bLogOpen)
            System.err.println("Failed to open NetSDK log");
    }
 
    /**
     * 高安全登录
     */
    public void loginWithHighLevel() {
        // 输入结构体参数
        NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstlnParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY() {
            {
                szIP = m_strIpAddr.getBytes();
                nPort = m_nPort;
                szUserName = m_strUser.getBytes();
                szPassword = m_strPassword.getBytes();
            }
        };
        // 输出结构体参数
        NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
 
        // 写入sdk
        m_hLoginHandle = netsdk.CLIENT_LoginWithHighLevelSecurity(pstlnParam, pstOutParam);
        if (m_hLoginHandle.longValue() == 0) {
            System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIpAddr, m_nPort,
                    netsdk.CLIENT_GetLastError());
        } else {
            deviceInfo = pstOutParam.stuDeviceInfo; // 获取设备信息
            System.out.println("Login Success");
            System.out.println("Device Address:" + m_strIpAddr);
            System.out.println("设备包含:" + deviceInfo.byChanNum + "个通道");
        }
    }
 
    /**
     * 退出
     */
    public void logOut() {
        if (m_hLoginHandle.longValue() != 0) {
            netsdk.CLIENT_Logout(m_hLoginHandle);
            System.out.println("LogOut Success");
        }
    }
 
    /**
     * 清理sdk环境并退出
     */
    public static void cleanAndExit() {
        if (bLogOpen) {
            netsdk.CLIENT_LogClose(); // 关闭sdk日志打印
        }
        netsdk.CLIENT_Cleanup(); // 进程关闭时,调用一次
        System.exit(0);
    }
 
    /**
     * 选择通道
     */
    private int channelId = -1;// 逻辑通道
 
    public void setChannelID() {
        System.out.println("请输入通道,从0开始计数,-1表示全部");
        Scanner sc = new Scanner(System.in);
        this.channelId = sc.nextInt();
    }
 
    /**
     * 订阅智能任务
     */
    public void AttachEventRealLoadPic() {
        // 先退订,设备不会对重复订阅作校验,重复订阅后会有重复的事件返回
        this.DetachEventRealLoadPic();
        // 需要图片
        int bNeedPicture = 1;
        m_attachHandle = netsdk.CLIENT_RealLoadPictureEx(m_hLoginHandle, channelId, NetSDKLib.EVENT_IVS_ALL,
                bNeedPicture, AnalyzerDataCB.getInstance(), null, null);
        if (m_attachHandle.longValue() != 0) {
            System.out.printf("Chn[%d] CLIENT_RealLoadPictureEx Success\n", channelId);
        } else {
            System.out.printf("Ch[%d] CLIENT_RealLoadPictureEx Failed!LastError = %s\n", channelId,
                    ToolKits.getErrorCode());
        }
    }
 
    /**
     * 报警事件(智能)回调
     */
    private static class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack {
        private final File picturePath;
        private static AnalyzerDataCB instance;
 
        private AnalyzerDataCB() {
            picturePath = new File("./AnalyzerPicture/");
            if (!picturePath.exists()) {
                picturePath.mkdirs();
            }
        }
 
        public static AnalyzerDataCB getInstance() {
            if (instance == null) {
                instance = new AnalyzerDataCB();
            }
            return instance;
        }
 
        public int invoke(LLong m_attachHandle, int dwAlarmType, Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,
                Pointer dwUser, int nSequence, Pointer reserved) {
            /**
             * 回调函数使用注意(防止卡回调) 1.不能再回调进行耗时操作,建议将数据、图片流、视频流等通过中间件和多线程抛出处理
             * 2.不能再回调调用netsdk的其他接口
             */
            if (m_attachHandle == null || m_attachHandle.longValue() == 0) {
                return -1;
            }
 
            switch (Objects.requireNonNull(EM_EVENT_IVS_TYPE.getEventType(dwAlarmType))) {
            case EVENT_IVS_FACEDETECT: { // 目标检测事件(对应 DEV_EVENT_FACEDETECT_INFO)
                System.out.println("目标检测事件----------------");
                NetSDKLib.DEV_EVENT_FACEDETECT_INFO msg = new NetSDKLib.DEV_EVENT_FACEDETECT_INFO();
                ToolKits.GetPointerData(pAlarmInfo, msg);
                int nPresetID = msg.stuIntelliCommInfo.nPresetID;
                System.out.println("nPresetID : " + nPresetID);
                break;
            }
            case EVENT_IVS_FACERECOGNITION: {// 目标识别事件(对应 DEV_EVENT_FACERECOGNITION_INFO)
                System.out.println("目标识别事件----------------");
                // 该智能事件结构体较大,提升性能可以参考TargetRecognitionExDemo,在初始化前调用CLIENT_SetIVSEventParseType指定结构体
                // DEV_EVENT_FACERECOGNITION_INFO_V1
                NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO msg = new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO();
                ToolKits.GetPointerData(pAlarmInfo, msg);
                System.out.println("szName : " + new String(msg.szName).trim() + "\n");
                System.out.println("时间(UTC):" + msg.UTC);
 
                /////////////// 保存全景图 ///////////////////
                if (msg.bGlobalScenePic == 1 && msg.stuGlobalScenePicInfo != null) {
                    String bigPicture = picturePath + "\\" + "Global" + System.currentTimeMillis() + ".jpg";
                    //ToolKits.savePicture(pBuffer, msg.stuGlobalScenePicInfo.dwOffSet,
                    //msg.stuGlobalScenePicInfo.dwFileLenth, bigPicture);
                }
                break;
            }
            case EVENT_IVS_HUMANTRAIT: {// 人体特征事件(对应 DEV_EVENT_HUMANTRAIT_INFO)
                System.out.println("人体特征事件------------");
                DEV_EVENT_HUMANTRAIT_INFO msg = new DEV_EVENT_HUMANTRAIT_INFO();
                ToolKits.GetPointerData(pAlarmInfo, msg);                
                System.out.println("通道号: "+msg.nChannelID);
                //帽子类型
                switch (msg.stuHumanAttributes.emCap) {
                    case 0:
                        System.out.println("未知");
                        break;
 
                    case 1:
                        System.out.println("普通帽子");
                        break;
 
                    case 2:
                        System.out.println("头盔");
                        break;
                    case 3:
                        System.out.println("安全帽");
                        break;
 
                    default:
                        System.out.println("未知");
                        break;
                }
                                                                
                // 保存全景图片
                if (msg.stuSceneImage.nLength > 0) {
                    String strFileName = picturePath + "\\" + System.currentTimeMillis() + "HumanTrait_全景图.jpg";
                    // ToolKits.savePicture(pBuffer, msg.stuSceneImage.nOffSet,
                    // msg.stuSceneImage.nLength, strFileName);
                } else {
                    System.out.println("无全景图");
                }
 
                // 保存人脸图
                if (msg.stuFaceImage.nLength > 0) {
                    String strFileName = picturePath + "\\" + System.currentTimeMillis() + "HumanTrait_人脸图.jpg";
                    // ToolKits.savePicture(pBuffer, msg.stuFaceImage.nOffSet,
                    // msg.stuFaceImage.nLength, strFileName);
                } else {
                    System.out.println("无人脸图");
                }
 
                // 保存人脸全景图
                if (msg.stuFaceSceneImage.nLength > 0) {
                    String strFileName = picturePath + "\\" + System.currentTimeMillis() + "HumanTrait_人脸全景图.jpg";
                    // ToolKits.savePicture(pBuffer, msg.stuFaceSceneImage.nOffSet,
                    // msg.stuFaceSceneImage.nLength, strFileName);
                } else {
                    System.out.println("无人脸全景图");
                }
 
                // 保存人体图
                if (msg.stuHumanImage.nLength > 0) {
                    String strFileName = picturePath + "\\" + System.currentTimeMillis() + "HumanTrait_人体图.jpg";
                    // ToolKits.savePicture(pBuffer, msg.stuHumanImage.nOffSet,
                    // msg.stuHumanImage.nLength, strFileName);
                } else {
                    System.out.println("无人体图");
                }
                break;
            }
            case EVENT_IVS_TRAFFICJUNCTION: {// 交通路口事件(对应 DEV_EVENT_TRAFFICJUNCTION_INFO)
                System.out.println("交通路口事件------------");
                // 路口事件,抓拍车牌
                NetSDKLib.DEV_EVENT_TRAFFICJUNCTION_INFO trafficJunction = new NetSDKLib.DEV_EVENT_TRAFFICJUNCTION_INFO();
                // 获取车牌信息
                ToolKits.GetPointerDataToStruct(pAlarmInfo, 0, trafficJunction);
                String date = trafficJunction.UTC.toStringTime();
                NetSDKLib.DEV_EVENT_TRAFFIC_TRAFFICCAR_INFO trafficCar = trafficJunction.stTrafficCar;
                try {
                    System.out.println(date + " traffic number:" + new String(trafficCar.szPlateNumber, encode)
                            + ",plate color:" + new String(trafficCar.szPlateColor, encode));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                System.out.println("emVehicleTypeByFunc = " + trafficJunction.stTrafficCar.emVehicleTypeByFunc);
                System.out.println("nSunBrand = " + trafficJunction.stTrafficCar.nSunBrand);
                System.out.println("nBrandYear = " + trafficJunction.stTrafficCar.nBrandYear);
 
                // save the picture
                String imageName = "trafficJunction_" + trafficJunction.UTC.toStringTitle() + ".jpg";
                String savePath = picturePath + "/" + imageName;
                ToolKits.savePicture(pBuffer, dwBufSize, savePath);
                System.out.println("save picture to " + savePath);
                NET_TRAFFICCAR_BLACK_LIST stuBlackList = trafficCar.stuBlackList;
                int nControlledRouteID = stuBlackList.nControlledRouteID;
                System.out.println("nControlledRouteID = " + nControlledRouteID);
                break;
 
            }
            default:
                // System.out.println("其他事件--------------------"+ dwAlarmType);
                break;
            }
            return 0;
        }
    }
 
    /**
     * 停止侦听智能事件
     */
    public void DetachEventRealLoadPic() {
        if (m_attachHandle.longValue() != 0) {
            netsdk.CLIENT_StopLoadPic(m_attachHandle);
        }
    }
 
    /**
     * 获取已添加的设备信息
     */
    public boolean getAllDeviceInfo() {
        String[] deviceIDs = null;// 设备id列表为空,默认查全部
        // String[] deviceIDs = { "CXbGbmlFA1E8GQ7A6P1C9R" };
        return getDeviceInfo(deviceIDs);
    }
 
    public boolean getDeviceInfo(String[] deviceIDs) { // 获取已添加的设备信息
        NET_IN_GET_DEVICE_LIST_INFO pstInParam = new NET_IN_GET_DEVICE_LIST_INFO();
        NET_OUT_GET_DEVICE_LIST_INFO pstOutParam = new NET_OUT_GET_DEVICE_LIST_INFO();
 
        if (deviceIDs != null) {
            pstInParam.nCount = deviceIDs.length;
            for (int i = 0; i < pstInParam.nCount; i++) {
                System.arraycopy(deviceIDs[i].getBytes(), 0, pstInParam.szDeviceIDsArr[i].szDeviceID, 0,
                        deviceIDs[i].getBytes().length);
            }
            pstOutParam.nMaxCount = pstInParam.nCount;
        } else {
            pstInParam.nCount = 0;
            pstOutParam.nMaxCount = NetSDKLib.MAX_LINK_DEVICE_NUM;
        }
 
        NET_GET_DEVICE_INFO[] deviceInfo = new NET_GET_DEVICE_INFO[pstOutParam.nMaxCount];
        for (int i = 0; i < pstOutParam.nMaxCount; i++) {
            deviceInfo[i] = new NET_GET_DEVICE_INFO();
        }
        pstOutParam.pstuDeviceInfo = new Memory(deviceInfo[0].size() * pstOutParam.nMaxCount);
        pstOutParam.pstuDeviceInfo.clear(deviceInfo[0].size() * pstOutParam.nMaxCount);
        ToolKits.SetStructArrToPointerData(deviceInfo, pstOutParam.pstuDeviceInfo); // 将数组内存拷贝到Pointer
 
        boolean bRet = netsdk.CLIENT_GetDeviceInfo(m_hLoginHandle, pstInParam, pstOutParam, 3000);
        if (!bRet) {
            System.err.printf("GetDeviceInfo Fail.Last Error[0x%x]\n", netsdk.CLIENT_GetLastError());
            return false;
        }
 
        ToolKits.GetPointerDataToStructArr(pstOutParam.pstuDeviceInfo, deviceInfo); // 将 Pointer 的内容 输出到 数组
        for (int i = 0; i < pstOutParam.nRetCount; i++) {
            System.out.println("设备ID:" + new String(deviceInfo[i].szDeviceID).trim());
            System.out.println("url:" + new String(deviceInfo[i].szUrl).trim());
            System.out.println("设备序列号:" + new String(deviceInfo[i].szSerialNo).trim());
            System.out.println("设备类型:" + new String(deviceInfo[i].szDeviceType).trim());
            System.out.println();
        }
        return true;
    }
 
    /**
     * 获取设备通道信息
     * 
     */
    public void getChannelInfo() {
        String deviceID = "7gC9c4470457t0V7P4434N";
        NET_IN_GET_CHANNEL_INFO pstInParam = new NET_IN_GET_CHANNEL_INFO();
        System.arraycopy(deviceID.getBytes(), 0, pstInParam.szDeviceID, 0, deviceID.getBytes().length);
 
        NET_GET_CHANNEL_INFO[] channelInfo = new NET_GET_CHANNEL_INFO[NetSDKLib.MAX_DEVICE_CHANNEL_NUM];
        for (int i = 0; i < channelInfo.length; i++) {
            channelInfo[i] = new NET_GET_CHANNEL_INFO();
        }
 
        NET_OUT_GET_CHANNEL_INFO pstOutParam = new NET_OUT_GET_CHANNEL_INFO();
        pstOutParam.nMaxCount = channelInfo.length; // 用户申请的通道个数
        pstOutParam.pstuChannelInfo = new Memory(channelInfo[0].size() * pstOutParam.nMaxCount);
        pstOutParam.pstuChannelInfo.clear(channelInfo[0].size() * pstOutParam.nMaxCount);
        ToolKits.SetStructArrToPointerData(channelInfo, pstOutParam.pstuChannelInfo); // 将数组内存拷贝到Pointer
 
        boolean bRet = netsdk.CLIENT_GetChannelInfo(m_hLoginHandle, pstInParam, pstOutParam, 3000);
        if (!bRet) {
            System.err.printf("GetChannelInfo Fail.Last Error[0x%x]\n", netsdk.CLIENT_GetLastError());
            return;
        }
        ToolKits.GetPointerDataToStructArr(pstOutParam.pstuChannelInfo, channelInfo);// 将 Pointer 的内容 输出到 数组
        System.out.println("用户申请的通道个数:" + pstOutParam.nMaxCount);
        System.out.println("实际返回的通道个数:" + pstOutParam.nRetCount);
        try {
            for (int i = 0; i < pstOutParam.nRetCount; i++) {
                System.out.println("--------获取设备通道信息结果信息---------");
                System.out.println("远程通道号:" + channelInfo[i].nRemoteChannel);
                System.out.println("分配的逻辑通道,-1表示未分配:" + channelInfo[i].nLogicChannel);
                System.out.println("通道名称:" + new String(channelInfo[i].szName, encode));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 设备、通道信息一起获取
     * 
     * @throws UnsupportedEncodingException
     */
    public void getDeviceInfoEx() throws UnsupportedEncodingException {
        String[] deviceIDs = null;// 设备id列表为空,默认查全部,数据返回太慢,性能较差不建议使用
        // String[] deviceIDs = { "CXbGbmlFA1EL8TPM4LVDFP","7gC9c4470457t0V7P4434N" };
        getDeviceInfoExDo(deviceIDs);
    }
 
    public void getDeviceInfoExDo(String[] deviceIDsArr) throws UnsupportedEncodingException {
        // 入参
        NET_IN_GET_DEVICE_INFO_EX pstInParam = new NET_IN_GET_DEVICE_INFO_EX();
        // 出参
        NET_OUT_GET_DEVICE_INFO_EX pstOutParam = new NET_OUT_GET_DEVICE_INFO_EX();
        String[] deviceIDs = deviceIDsArr;
        if (deviceIDs != null) {
            pstInParam.nCount = deviceIDs.length;// 长度不能大于32
            for (int i = 0; i < pstInParam.nCount; i++) {
                System.arraycopy(deviceIDs[i].getBytes(), 0, pstInParam.szDeviceIDs[i].szDeviceID, 0,
                        deviceIDs[i].getBytes().length);
            }
            pstOutParam.nMaxCount = deviceIDs.length; // 用户申请的通道个数
        } else {
            pstInParam.nCount = 0;
            pstOutParam.nMaxCount = NetSDKLib.MAX_LINK_DEVICE_NUM;
        }
        pstInParam.write();
 
        // 初始化通道信息
        // int nMaxChannelCount = NetSDKLib.MAX_DEVICE_CHANNEL_NUM;
        int nMaxChannelCount = 10;// 每个设备用户申请的通道个数
        NET_DEVICE_CHANNEL_INFO[] channalInfo = new NET_DEVICE_CHANNEL_INFO[nMaxChannelCount];
        for (int i = 0; i < channalInfo.length; i++) {
            channalInfo[i] = new NET_DEVICE_CHANNEL_INFO();
        }
 
        // 初始化设备的结果信息
        NET_GET_DEVICE_INFO_EX[] deviceInfo = new NET_GET_DEVICE_INFO_EX[pstOutParam.nMaxCount];
        for (int i = 0; i < deviceInfo.length; i++) {
            NET_GET_DEVICE_INFO_EX info = new NET_GET_DEVICE_INFO_EX();
            info.nMaxChannelCount = nMaxChannelCount; // 每个设备用户申请的通道个数
            info.pstuChannelsInfo = new Memory(channalInfo[0].size() * nMaxChannelCount);
            info.pstuChannelsInfo.clear(channalInfo[0].size() * nMaxChannelCount);
            // 将数组内存拷贝到Pointer
            ToolKits.SetStructArrToPointerData(channalInfo, info.pstuChannelsInfo);
            deviceInfo[i] = info;
        }
 
        pstOutParam.nMaxCount = pstOutParam.nMaxCount; // 用户申请的通道个数
        pstOutParam.pstuDeviceInfo = new Memory(deviceInfo[0].size() * pstOutParam.nMaxCount);
        pstOutParam.pstuDeviceInfo.clear(deviceInfo[0].size() * pstOutParam.nMaxCount);
        ToolKits.SetStructArrToPointerData(deviceInfo, pstOutParam.pstuDeviceInfo); // 将数组内存拷贝到Pointer
        pstOutParam.write();
        boolean flg = netsdk.CLIENT_GetDeviceInfoEx(m_hLoginHandle, pstInParam.getPointer(), pstOutParam.getPointer(),
                4000);
        pstInParam.read();
        if (flg) {
            System.out.println("CLIENT_GetDeviceInfoEx Succeed!");
            pstOutParam.read();
            System.out.println("实际返回的设备个数: " + pstOutParam.nRetCount);
            ToolKits.GetPointerDataToStructArr(pstOutParam.pstuDeviceInfo, deviceInfo); // 将 Pointer 的内容 输出到 数组
            for (int i = 0; i < pstOutParam.nRetCount; i++) {
                System.out.println("第" + (i + 1) + "设备信息------------------");
                System.out.println("设备ID:" + new String(deviceInfo[i].szDeviceID).trim());
                System.out.println("url:" + new String(deviceInfo[i].szUrl).trim());
                System.out.println("设备序列号:" + new String(deviceInfo[i].szSerialNo).trim());
                System.out.println("设备类型:" + new String(deviceInfo[i].szDeviceType).trim());
                System.out.println();
                System.out.println("用户申请的通道个数: " + deviceInfo[i].nMaxChannelCount);
                System.out.println("实际返回的通道个数: " + deviceInfo[i].nRetChannelCount);
                ToolKits.GetPointerDataToStructArr(deviceInfo[i].pstuChannelsInfo, channalInfo);
                for (int j = 0; j < deviceInfo[i].nRetChannelCount; j++) {
                    System.out.println("第" + (j + 1) + "通道信息---------");
                    System.out.println("远程通道号:" + channalInfo[j].nRemoteChannel);
                    System.out.println("分配的逻辑通道,-1表示未分配:" + channalInfo[j].nLogicChannel);
                    System.out.println("通道名称:" + new String(channalInfo[j].szName, encode));
                }
            }
 
        } else {
            System.out.println("CLIENT_GetDeviceInfoEx Failed, Error:" + ToolKits.getErrorCode());
        }
 
    }
 
    private int nToken;
 
    /**
     * 获取检测Token
     */
    public void faceRServerGetDetectToken() {
        // 入参
        NET_IN_FACERSERVER_GETDETEVTTOKEN pstInParam = new NET_IN_FACERSERVER_GETDETEVTTOKEN();
        pstInParam.write();
        // 出参
        NET_OUT_FACERSERVER_GETDETEVTTOKEN pstOutParam = new NET_OUT_FACERSERVER_GETDETEVTTOKEN();
        pstOutParam.write();
        boolean flg = netsdk.CLIENT_FaceRServerGetDetectToken(m_hLoginHandle, pstInParam.getPointer(),
                pstOutParam.getPointer(), 4000);
        pstInParam.read();
        pstOutParam.read();
        if (flg) {
            System.out.println("faceRServerGetDetectToken Succeed!");
            System.out.println("获取到的查询令牌: " + pstOutParam.nToken);
            nToken = pstOutParam.nToken;
        } else {
            System.out.println("faceRServerGetDetectToken Failed, Error:" + ToolKits.getErrorCode());
        }
    }
 
    private NetSDKLib.LLong attachFaceHandle = new NetSDKLib.LLong(0);
 
 
    
    
    /**
     * 查询人脸库信息
     */
    public void findGroupInfo() {
        // groupId 需要查找的人脸库ID; 为空表示查找所有的人脸库
        //String groupId = "1";
        String groupId = "";
        // 入参
        NetSDKLib.NET_IN_FIND_GROUP_INFO stIn = new NetSDKLib.NET_IN_FIND_GROUP_INFO();
        System.arraycopy(groupId.getBytes(), 0, stIn.szGroupId, 0, groupId.getBytes().length);
 
        // 出参
        int max = 20;
        NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[] groupInfo = new NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[max];
        for (int i = 0; i < max; i++) {
            groupInfo[i] = new NetSDKLib.NET_FACERECONGNITION_GROUP_INFO();
        }
 
        NetSDKLib.NET_OUT_FIND_GROUP_INFO stOut = new NetSDKLib.NET_OUT_FIND_GROUP_INFO();
        stOut.pGroupInfos = new Memory(groupInfo[0].size() * 20); // Pointer初始化
        stOut.pGroupInfos.clear(groupInfo[0].size() * 20);
        stOut.nMaxGroupNum = max;
 
        ToolKits.SetStructArrToPointerData(groupInfo, stOut.pGroupInfos); // 将数组内存拷贝给Pointer
 
        if (netsdk.CLIENT_FindGroupInfo(m_hLoginHandle, stIn, stOut, 4000)) {
            ToolKits.GetPointerDataToStructArr(stOut.pGroupInfos, groupInfo); // 将Pointer的值输出到数组NET_FACERECONGNITION_GROUP_INFO
            System.out.println("FindGroupInfo successful,num:"+stOut.nRetGroupNum);
            for (int i = 0; i < stOut.nRetGroupNum; i++) {
                // 人脸库ID
                System.out.println("[" + i + "]szGroupId: " + new String(groupInfo[i].szGroupId).trim());
                // 人脸库名称
                try {
                    System.out.println("[" + i + "]szGroupName: " + new String(groupInfo[i].szGroupName, encode).trim());
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                // 相似度
                String nSimilarityCount = "";
                for (int j = 0; j < groupInfo[i].nRetSimilarityCount; j++) {
                    nSimilarityCount = nSimilarityCount + "  " + String.valueOf(groupInfo[i].nSimilarity[j]);
                }
                System.out.println("[" + i + "]nSimilarityCount: " + nSimilarityCount);
                // 当前组绑定到的视频通道号列表
                String nChannelCount = "";
                for (int j = 0; j < groupInfo[i].nRetChnCount; j++) {
                    nChannelCount = nChannelCount + "  " + String.valueOf(groupInfo[i].nChannel[j]);
                }
                System.out.println("[" + i + "]nChannelCount: " + nChannelCount);
                // 人员组备注信息
                System.out.println("[" + i + "]szGroupRemarks: " + new String(groupInfo[i].szGroupRemarks).trim());
                // 当前组内人员数
                System.out.println("[" + i + "]nGroupSize: " + groupInfo[i].nGroupSize);
                // 人员组类型,详见EM_FACE_DB_TYPE, 取值为EM_FACE_DB_TYPE中的值
                System.out.println("[" + i + "]emFaceDBType: " + groupInfo[i].emFaceDBType);
            }
        } else {
            System.err.println("查询人员信息失败" + ToolKits.getErrorCode());
        }
    }
    
    /**
     * 添加人脸库
     */
    public boolean addFaceRecognitionGroup() {
 
        String groupName = "禁止名单数据库1";
 
        NetSDKLib.NET_ADD_FACERECONGNITION_GROUP_INFO addGroupInfo = new NetSDKLib.NET_ADD_FACERECONGNITION_GROUP_INFO();
        try {
            System.arraycopy(groupName.getBytes(encode), 0, addGroupInfo.stuGroupInfo.szGroupName, 0,
                    groupName.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        addGroupInfo.stuGroupInfo.emFaceDBType = NetSDKLib.EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_BLACKLIST;//禁止名单数据库
 
        // 入参
        NetSDKLib.NET_IN_OPERATE_FACERECONGNITION_GROUP stIn = new NetSDKLib.NET_IN_OPERATE_FACERECONGNITION_GROUP();
        stIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_ADD; // 添加人员组信息
        stIn.pOPerateInfo = addGroupInfo.getPointer();
 
        // 出参
        NetSDKLib.NET_OUT_OPERATE_FACERECONGNITION_GROUP stOut = new NetSDKLib.NET_OUT_OPERATE_FACERECONGNITION_GROUP();
 
        addGroupInfo.write();
        boolean bRet = netsdk.CLIENT_OperateFaceRecognitionGroup(m_hLoginHandle, stIn, stOut, 4000);
        addGroupInfo.read();
 
        if (bRet) {
            System.out.println("人员组ID : " + new String(stOut.szGroupId).trim()); // 新增记录的人员组ID,唯一标识一组人员
            System.out.println("添加人脸库成功");
        } else {
            System.out.println("添加人脸库失败:" + ToolKits.getErrorCode());
            return false;
        }
 
        return true;
    }
 
    /**
     * 修改人脸库
     */
    public boolean modifyFaceRecognitionGroup() {
        String groupName = "禁止名单数据库";
        String groupId = "3";
 
        NetSDKLib.NET_MODIFY_FACERECONGNITION_GROUP_INFO modifyGroupInfo = new NetSDKLib.NET_MODIFY_FACERECONGNITION_GROUP_INFO();
        try {
            System.arraycopy(groupName.getBytes(encode), 0, modifyGroupInfo.stuGroupInfo.szGroupName, 0,
                    groupName.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.arraycopy(groupId.getBytes(), 0, modifyGroupInfo.stuGroupInfo.szGroupId, 0, groupId.getBytes().length); // 给人员组ID赋值,要用数组拷贝
        modifyGroupInfo.stuGroupInfo.emFaceDBType = NetSDKLib.EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_BLACKLIST;//禁止名单数据库
        // 入参
        NetSDKLib.NET_IN_OPERATE_FACERECONGNITION_GROUP stIn = new NetSDKLib.NET_IN_OPERATE_FACERECONGNITION_GROUP();
        stIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_MODIFY; // 修改人员组信息
        stIn.pOPerateInfo = modifyGroupInfo.getPointer();
 
        // 出参
        NetSDKLib.NET_OUT_OPERATE_FACERECONGNITION_GROUP stOut = new NetSDKLib.NET_OUT_OPERATE_FACERECONGNITION_GROUP();
 
        modifyGroupInfo.write();
        boolean bRet = netsdk.CLIENT_OperateFaceRecognitionGroup(m_hLoginHandle, stIn, stOut, 4000);
        modifyGroupInfo.read();
 
        if (bRet) {
            System.out.println("修改人脸库成功");
        } else {
            System.out.println("修改人脸库失败:" + ToolKits.getErrorCode());
            return false;
        }
 
        return true;
    }
 
    /**
     * 删除人脸库
     */
    public boolean deleteFaceRecognitionGroup() {
        String groupId = "3";
        NetSDKLib.NET_DELETE_FACERECONGNITION_GROUP_INFO deleteGroupInfo = new NetSDKLib.NET_DELETE_FACERECONGNITION_GROUP_INFO();
        System.arraycopy(groupId.getBytes(), 0, deleteGroupInfo.szGroupId, 0, groupId.getBytes().length); // 给人员组ID赋值,要用数组拷贝
 
        // 入参
        NetSDKLib.NET_IN_OPERATE_FACERECONGNITION_GROUP stIn = new NetSDKLib.NET_IN_OPERATE_FACERECONGNITION_GROUP();
        stIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_DELETE; // 删除人员组信息
        stIn.pOPerateInfo = deleteGroupInfo.getPointer();
 
        // 出参
        NetSDKLib.NET_OUT_OPERATE_FACERECONGNITION_GROUP stOut = new NetSDKLib.NET_OUT_OPERATE_FACERECONGNITION_GROUP();
 
        deleteGroupInfo.write();
        boolean bRet = netsdk.CLIENT_OperateFaceRecognitionGroup(m_hLoginHandle, stIn, stOut, 4000);
        deleteGroupInfo.read();
 
        if (bRet) {
            System.out.println("删除人脸库成功!");
        } else {
            System.out.println("删除人脸库失败:" + ToolKits.getErrorCode());
            return false;
        }
 
        return true;
    }
    
 
    
 
    /**
     * 添加人员信息(即注册人脸)
     * @param groupId 组ID(人脸库ID) 
     * @param nPicBufLen 图片大小
     * @param width 图片宽
     * @param height 图片高 
     * @param memory  保存图片的缓存
     * @param personName 人员名称
     * @param bySex 性别
     * @param birthday 生日(年月日数组)
     * @param province 省份
     * @param id 证件编号
     * @param byIdType 证件类型
     */
    public boolean addFaceRecognitionDB() {                
        
        // 入参
        NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
        stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_ADD;
        
        ///////// 使用人员扩展信息 //////////
        stuIn.bUsePersonInfoEx = 1;   
        
        // 组ID设置
        String groupId = "3";
        System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
        
        // 生日设置
        String[] birthday = {"2000","7","26"};
        stuIn.stPersonInfoEx.wYear = (short)Integer.parseInt(birthday[0]);
        stuIn.stPersonInfoEx.byMonth = (byte)Integer.parseInt(birthday[1]);
        stuIn.stPersonInfoEx.byDay = (byte)Integer.parseInt(birthday[2]);
        
        // 性别,1-男,2-女,作为查询条件时,此参数填0,则表示此参数无效    
        byte bySex = 1;
        stuIn.stPersonInfoEx.bySex = bySex;    
        
        // 人员名字    
        String personName = "张生1";
        try {
            System.arraycopy(personName.getBytes(encode), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } 
        
        // 证件类型,详见 EM_CERTIFICATE_TYPE
        byte byIdType = 1;
        stuIn.stPersonInfoEx.byIDType = byIdType;  
        
        // 人员唯一标识(证件号码,工号,或其他编号)
        String id ="629006200017264513";
        System.arraycopy(id.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, id.getBytes().length);                       
        
        // 国际,符合ISO3166规范
        System.arraycopy("CN".getBytes(), 0, stuIn.stPersonInfoEx.szCountry, 0, "CN".getBytes().length);    
        
        // 省份
        String province = "HB";
        try {
            System.arraycopy(province.getBytes(encode), 0, stuIn.stPersonInfoEx.szProvince, 0, province.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }  
        
         // 城市
        String city = "WH";
        try {
            System.arraycopy(city.getBytes(encode), 0, stuIn.stPersonInfoEx.szCity, 0, city.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }  
 
        // 当前接口的文件大小为int,这里进行强制转换,
        // 意味着只能支持2G以下的文件
        String selectImagePath ="D:\\297.jpg";
        int nPicBufLen = (int)ToolKits.GetFileSize(selectImagePath);   // 图片大小
        // 读取文件大小失败
        if (nPicBufLen <= 0) {
            System.out.println("读取图片大小失败");
            return false;
        }
        Memory memory = new Memory(nPicBufLen);   // 申请缓存
        memory.clear();        
        if (!ToolKits.ReadAllFileToMemory(selectImagePath, memory)) {
            System.out.printf("read all file from %s to memory failed!!!\n");
            return false;
        }                
        
        // 图片张数、大小、宽、高、缓存设置
        if(memory != null) {
            stuIn.stPersonInfoEx.wFacePicNum = 1; // 图片张数
            // 图片是否算法检测出来的检测过的提交识别服务器时,
            // 则不需要再时检测定位抠图,1:检测过的,0:没有检测过
            stuIn.stPersonInfo.szFacePicInfo[0].bIsDetected = 0;
            stuIn.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;
            stuIn.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = nPicBufLen;
            //stuIn.stPersonInfoEx.szFacePicInfo[0].wWidth = (short)0;
            //stuIn.stPersonInfoEx.szFacePicInfo[0].wHeight = (short)0;            
            stuIn.nBufferLen = nPicBufLen;
            stuIn.pBuffer = memory;
        }
        
        // 出参
        NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
        
        stuIn.write();
        if(netsdk.CLIENT_OperateFaceRecognitionDB(m_hLoginHandle, stuIn, stuOut, 3000)) {
            System.out.println("添加人员信息成功!");
        } else {
            System.out.println("添加人员信息失败!"+ ToolKits.getErrorCode());
            return false;
        }
        stuIn.read();
        System.out.println("人员唯一标识符szUID: "+new String(stuOut.szUID).trim());//000011692235373649020050150005
 
        return true;
    }
    
    /**
     * 修改人员信息(即注册人脸)
     * @param groupId 组ID(人脸库ID) 
     * @param szUID 人员唯一标识符
     * @param nPicBufLen 图片大小
     * @param width 图片宽
     * @param height 图片高 
     * @param memory  保存图片的缓存
     * @param personName 人员名称
     * @param bySex 性别
     * @param birthday 生日(年月日数组)
     * @param province 省份
     * @param id 证件编号
     * @param byIdType 证件类型
     */
    public boolean modifyFaceRecognitionDB() {
        // 入参
        NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
        stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_MODIFY;
        
        ///////// 使用人员扩展信息  ////////
        stuIn.bUsePersonInfoEx = 1;    
        
        // 组ID设置
        String groupId = "1";
        System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
        
        // UID设置
        String szUID = "000011692252252515025540162542";
        System.arraycopy(szUID.getBytes(), 0, stuIn.stPersonInfoEx.szUID, 0, szUID.getBytes().length); 
        
        // 生日设置
        String[] birthday = {"2001","7","26"};
        stuIn.stPersonInfoEx.wYear = (short)Integer.parseInt(birthday[0]);
        stuIn.stPersonInfoEx.byMonth = (byte)Integer.parseInt(birthday[1]);
        stuIn.stPersonInfoEx.byDay = (byte)Integer.parseInt(birthday[2]);
        
        // 性别,1-男,2-女,作为查询条件时,此参数填0,则表示此参数无效
        byte bySex = 1;
        stuIn.stPersonInfoEx.bySex = bySex;    
        
        // 人员名字    
        String personName = "张生";
        try {
            System.arraycopy(personName.getBytes(encode), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } 
        
        // 证件类型,详见 EM_CERTIFICATE_TYPE
        byte byIdType = 1;
        stuIn.stPersonInfoEx.byIDType = byIdType;  
        
        // 人员唯一标识(证件号码,工号,或其他编号)
        String id ="629006200017264512";
        System.arraycopy(id.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, id.getBytes().length);                       
        
        // 国际,符合ISO3166规范
        System.arraycopy("CN".getBytes(), 0, stuIn.stPersonInfoEx.szCountry, 0, "CN".getBytes().length);         
        
         // 省份
        String province = "HB";
        try {
            System.arraycopy(province.getBytes(encode), 0, stuIn.stPersonInfoEx.szProvince, 0, province.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }  
        
        // 城市
        String city = "WH";
        try {
            System.arraycopy(city.getBytes(encode), 0, stuIn.stPersonInfoEx.szCity, 0, city.getBytes(encode).length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } 
 
        // 出参
        NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
        
        stuIn.write();
        if(netsdk.CLIENT_OperateFaceRecognitionDB(m_hLoginHandle, stuIn, stuOut, 3000)) {
            System.out.println("修改人员信息成功!");
        } else {
            System.out.println("修改人员信息失败!"+ ToolKits.getErrorCode());
            return false;
        }
        stuIn.read();
 
        return true;
    }
    
    /**
     * 删除人员信息(即删除人脸)
     * @param groupId 人脸库ID
     * @param sUID  人员唯一标识符
     */
    public boolean delFaceRecognitionDB() {    
        // 入参
        NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
        stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_DELETE;
    
        //////// 使用人员扩展信息  //////////
        stuIn.bUsePersonInfoEx = 1;    
        
        // GroupID 赋值
        String groupId ="1";
        System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
 
        // UID赋值
        String sUID ="000011692252252515025540162542";
        System.arraycopy(sUID.getBytes(), 0, stuIn.stPersonInfoEx.szUID, 0, sUID.getBytes().length);
 
        // 出参
        NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
 
        if(netsdk.CLIENT_OperateFaceRecognitionDB(m_hLoginHandle, stuIn, stuOut, 3000)) {
            System.out.println("删除人员信息成功!");
        } else {
            System.out.println("删除人员信息失败!"+ ToolKits.getErrorCode());
            return false;
        }        
        return true;
    }
    
    /**
     * 通过UID删除人员信息和人脸样本
     * @param sUID  人员唯一标识符
     */
    public boolean delFaceRecognitionDBByUID() {            
        String[] UIDS = {"000011692252252515025540162542"};
        // 入参
        NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
        stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_DELETE_BY_UID;
        //添加的UID个数 
        int nMaxNum = UIDS.length;
        // 先初始化用户信息数组
        NET_UID_CHAR[] uidArr = new NET_UID_CHAR[nMaxNum];
        for (int i = 0; i < nMaxNum; i++) {
            uidArr[i] = new NET_UID_CHAR();
        }        
        // UID赋值
        for (int i = 0; i < nMaxNum; i++) {
            System.arraycopy(UIDS[i].getBytes(), 0,uidArr[i].szUID, 0, UIDS[i].getBytes().length);
        }
        stuIn.nUIDNum = nMaxNum;
        stuIn.stuUIDs = new Memory(uidArr[0].size() * nMaxNum); // 申请内存
        stuIn.stuUIDs.clear(uidArr[0].size() * nMaxNum);
        // 将用户信息传给指针
        ToolKits.SetStructArrToPointerData(uidArr, stuIn.stuUIDs);        
 
        // 出参
        NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
 
        if(netsdk.CLIENT_OperateFaceRecognitionDB(m_hLoginHandle, stuIn, stuOut, 3000)) {
            System.out.println("删除人员信息成功!");
        } else {
            System.out.println("删除人员信息失败!"+ToolKits.getErrorCode());
            return false;
        }     
        System.out.println("错误码个数: "+stuOut.nErrorCodeNum);
        return true;
    }
    
    
    
    /**
     * 以人脸库的角度进行布控
     * @param groupId 人脸库ID
     */
    public boolean putFaceRecognitionDisposition() {
        // 入参
        NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO stIn = new NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO();
        // 人脸库ID
        String groupId = "3";
        System.arraycopy(groupId.getBytes(), 0, stIn.szGroupId, 0, groupId.getBytes().length);
        // 布控视频通道个数    
        stIn.nDispositionChnNum = 1;        
        stIn.stuDispositionChnInfo[0].nSimilary = 80;
        stIn.stuDispositionChnInfo[0].nChannelID = 6;
        
        // 出参
        NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO stOut = new NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO();
        
        if(netsdk.CLIENT_FaceRecognitionPutDisposition(m_hLoginHandle, stIn, stOut, 4000)) {
           System.out.println("通道布控结果个数:" + stOut.nReportCnt);            
           for(int i = 0; i < stOut.nReportCnt; i++) {
               if(stOut.bReport[i] == 1) {
                        System.out.println("通道布控结果 : 成功。");
                } else {
                        System.err.println("通道布控结果 : 失败。");            
               }
           }    
        } else {
            return false;
        }
        return true;
    }
    
    /**
     * 以人脸库的角度进行撤控
     * @param groupId 人脸库ID
     */
    public boolean delFaceRecognitionDisposition() {
        // 入参
        NET_IN_FACE_RECOGNITION_DEL_DISPOSITION_INFO stIn = new NET_IN_FACE_RECOGNITION_DEL_DISPOSITION_INFO();
        // 人脸库ID
        String groupId = "1";
        System.arraycopy(groupId.getBytes(), 0, stIn.szGroupId, 0, groupId.getBytes().length);
        
        // 撤控视频通道个数
        stIn.nDispositionChnNum = 1; 
        stIn.nDispositionChn[0] = 6;
        
        // 出参
        NET_OUT_FACE_RECOGNITION_DEL_DISPOSITION_INFO stOut = new NET_OUT_FACE_RECOGNITION_DEL_DISPOSITION_INFO();
        
        if( netsdk.CLIENT_FaceRecognitionDelDisposition(m_hLoginHandle, stIn, stOut, 4000)) {
            System.out.println("通道撤控结果个数:" + stOut.nReportCnt);            
            for(int i = 0; i < stOut.nReportCnt; i++) {
                if(stOut.bReport[i] == 1) {
                    System.out.println("通道撤控结果 : 成功。");
                } else {
                    System.err.println("通道撤控结果 : 失败。");
                }
            }
        } else {
            return false;
        }
        return true;
    }
    
    /**
     * 订阅检测结果
     */
    public void attachDetectMultiFaceState() {
        // 获取检测Token
        faceRServerGetDetectToken();
        // 入参
        NET_IN_MULTIFACE_DETECT_STATE pstInParam = new NET_IN_MULTIFACE_DETECT_STATE();
        pstInParam.nTokensNum = 1;
        pstInParam.nTokens[0] = nToken; // 查询令牌
        pstInParam.cbMultiFaceDetectState = MultiFaceDetectState.getInstance();
        pstInParam.write();
        // 出参
        NET_OUT_MULTIFACE_DETECT_STATE pstOutParam = new NET_OUT_MULTIFACE_DETECT_STATE();
        pstOutParam.write();
        attachFaceHandle = netsdk.CLIENT_AttachDetectMultiFaceState(m_hLoginHandle, pstInParam.getPointer(),
                pstOutParam.getPointer(), 4000);
        pstInParam.read();
        pstOutParam.read();
        if (attachFaceHandle.longValue() != 0) {
            System.out.println("AttachFaceFindState Succeed!");
        } else {
            System.out.println("AttachFaceFindState Failed, Error:" + ToolKits.getErrorCode());
        }
    }
 
    private static class MultiFaceDetectState implements NetSDKLib.fMultiFaceDetectState {
        private static MultiFaceDetectState instance;
 
        public static MultiFaceDetectState getInstance() {
            if (instance == null) {
                instance = new MultiFaceDetectState();
            }
            return instance;
        }
 
        @Override
        public void invoke(LLong lAttachHandle, Pointer pstStates, Pointer dwUser) {
            NET_CB_MULTIFACE_DETECT_STATE msg = new NET_CB_MULTIFACE_DETECT_STATE();
            ToolKits.GetPointerData(pstStates, msg);
            System.out.println("检测进度: " + msg.nProgress);
            System.out.println("大图ID: " + msg.stuImageRelation.nBigPicId);
            System.out.println("大图中小图张数: " + msg.stuImageRelation.nSmallPicNum);
            NET_SMALL_PIC_INFO[] stuSmallPicInfo = msg.stuImageRelation.stuSmallPicInfo;
            for (int i = 0; i < msg.stuImageRelation.nSmallPicNum; i++) {
                System.out.println("第" + (i + 1) + "张小图-------");
                System.out.println("小图ID: " + stuSmallPicInfo[i].nSmallPicId);
                System.out.println("目标类型: " + stuSmallPicInfo[i].emDetectObjType);
                System.out.println("小图在大图中的位置: " + stuSmallPicInfo[i].stuRect.toString());
            }
            System.out.println(
                    "大图检测小图结果错误码: " + EM_MULTIFACE_DETECT_ERRCODE.getNoteByValue(msg.stuImageRelation.emDetectErrCode));
        }
 
    }
 
    /**
     * 上传图片进行检测
     */
    public void faceRecognitionDetectMultiFace() {
        NET_IN_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO stIn = new NET_IN_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO();
        String picPath = "D:\\297.jpg";
        byte[] picBuf = ToolKits.readPictureToByteArray(picPath);
        stIn.bBigPicInfoExEnable = 1;
        //stIn.emDetectObjType = NetSDKLib.EM_OBJECT_TYPE.EM_OBJECT_TYPE_VECHILE;// 目标类型 -机动车
        stIn.emDetectObjType = NetSDKLib.EM_OBJECT_TYPE.EM_OBJECT_TYPE_FACE;// 目标类型-人脸
        stIn.nBigPicNumEx = 1;
        stIn.stuBigPicInfoEx[0].dwOffSet = 0;
        //stIn.stuBigPicInfoEx[0].emObjectType = EM_DETECT_OBJECT_TYPE.EM_DETECT_OBJECT_TYPE_VEHICLE.getValue();// 目标类型-机动车
        stIn.stuBigPicInfoEx[0].emObjectType = EM_DETECT_OBJECT_TYPE.EM_DETECT_OBJECT_TYPE_FACE.getValue();// 目标类型-人脸
        stIn.stuBigPicInfoEx[0].dwFileLenth = picBuf.length;
        stIn.stuBigPicInfoEx[0].nPicID = 666;// 大图ID,设置为唯一值
        stIn.nBufferLen = picBuf.length;
        stIn.pBuffer = new Memory(picBuf.length);
        stIn.pBuffer.write(0, picBuf, 0, picBuf.length);
        stIn.nToken = nToken;
 
        NET_OUT_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO stOut = new NET_OUT_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO();
        stIn.write();
        stOut.write();
        boolean bRet = netsdk.CLIENT_FaceRecognitionDetectMultiFace(m_hLoginHandle, stIn.getPointer(),
                stOut.getPointer(), 3000);
        stIn.read();
        stOut.read();
        if (bRet) {
            System.out.println("CLIENT_FaceRecognitionDetectMultiFace success");
        } else {
            System.out.println("CLIENT_FaceRecognitionDetectMultiFace failed");
            System.out.println("error = " + ToolKits.getErrorCode());
        }
    }
 
    /**
     * 取消订阅
     */
    public void detachDetectMultiFaceState() {
        if (attachFaceHandle.longValue() != 0) {
            netsdk.CLIENT_DetachDetectMultiFaceState(attachFaceHandle);
        }
    }
    
    private final AnalyseTaskModule analyseTaskModule = new AnalyseTaskModule(netsdk);
    /**
     * 1:1,图片比对
     */
    public void matchPicture() {
        try {
            int result = analyseTaskModule.matchImage(m_hLoginHandle.longValue(), new FileInputStream(new File("D:/296.jpg")), new FileInputStream(new File("D:/测试图片/1.jpg")), 3000);
            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
     }
 
    
 
    public class IntPoint extends NetSDKLib.SdkStructure {
 
        public int value;
 
        public IntPoint() {
        }
 
        public IntPoint(int value) {
            this.value = value;
        }
    }
    /**
     * 机动车以图搜图
     */
    public void searchByVechilePictureMultiVer() {
        searchByVechilePictureEx("2023-01-01", "2023-04-20", "50");
    }
 
    /**
     * 机动车以图搜图
     * 
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param chn       通道号
     * @param similary  相似度
     * @param memory    图片缓存
     * @param nPicLen   图片大小
     */
    public void searchByVechilePictureEx(String startTime, String endTime, String similary) {
        String[] startTimeStr = startTime.split("-");
        String[] endTimeStr = endTime.split("-");
        NET_IN_STARTMULTIFIND_FACERECONGNITION_EX stInStartFind = new NET_IN_STARTMULTIFIND_FACERECONGNITION_EX();
        // 通道号
        stInStartFind.nChannelCount = 4;
        IntPoint[] intPoints = new IntPoint[4];
        for (int i = 0; i < 4; i++) {
            intPoints[i] = new IntPoint(i);
        }
        stInStartFind.pChannelID = new Memory(intPoints[0].size() * stInStartFind.nChannelCount);
        stInStartFind.pChannelID.clear(intPoints[0].size() * stInStartFind.nChannelCount);
        ToolKits.SetStructArrToPointerData(intPoints, stInStartFind.pChannelID);
        stInStartFind.emObjectType = NetSDKLib.EM_OBJECT_TYPE.EM_OBJECT_TYPE_VECHILE;
        // 相似度
        if (!similary.equals("")) {
            stInStartFind.stMatchOptions.nSimilarity = Integer.parseInt(similary);//相似度
            stInStartFind.stMatchOptions.nMaxCandidate = 1000;//报告的最大候选个数(根据相似度进行排序,取相似度最大的候选人数报告)
        }
 
        stInStartFind.stFilterInfo.nGroupIdNum = 0;
        stInStartFind.stFilterInfo.nRangeNum = 1;
        stInStartFind.stFilterInfo.szRange[0] = NetSDKLib.EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_HISTORY; // 历史数据库
        stInStartFind.stFilterInfo.stStartTime.dwYear = Integer.parseInt(startTimeStr[0]);
        stInStartFind.stFilterInfo.stStartTime.dwMonth = Integer.parseInt(startTimeStr[1]);
        stInStartFind.stFilterInfo.stStartTime.dwDay = Integer.parseInt(startTimeStr[2]);
        stInStartFind.stFilterInfo.stEndTime.dwYear = Integer.parseInt(endTimeStr[0]);
        stInStartFind.stFilterInfo.stEndTime.dwMonth = Integer.parseInt(endTimeStr[1]);
        stInStartFind.stFilterInfo.stEndTime.dwDay = Integer.parseInt(endTimeStr[2]);
 
        // 图片信息
        String picPath = "D:\\297.jpg";
        byte[] picBuf = ToolKits.readPictureToByteArray(picPath);
        stInStartFind.pBuffer = new Memory(picBuf.length);
        stInStartFind.pBuffer.write(0, picBuf, 0, picBuf.length);
        stInStartFind.nBufferLen = picBuf.length;
        stInStartFind.bPersonEx2Enable = 1; // 人员信息查询条件是否有效, 并使用扩展结构体
        stInStartFind.stPersonInfoEx2.bPersonExEnable = 0;
 
        stInStartFind.stPersonInfoEx2.nFacePicNumEx = 1;
        stInStartFind.stPersonInfoEx2.stuFacePicInfoEx[0].dwOffSet = 0;
        stInStartFind.stPersonInfoEx2.stuFacePicInfoEx[0].dwFileLenth = picBuf.length;
 
        stInStartFind.stPersonInfoEx2.nBoundingBoxNum = 1;// 大图内小图坐标信息
        stInStartFind.stPersonInfoEx2.stuBoundingBox[0].nTop = 174;
        stInStartFind.stPersonInfoEx2.stuBoundingBox[0].nLeft = 1706;
        stInStartFind.stPersonInfoEx2.stuBoundingBox[0].nRight = 4040;
        stInStartFind.stPersonInfoEx2.stuBoundingBox[0].nBottom = 4573;
        stInStartFind.stPersonInfoEx2.nTrafficCarAttributeNum = 1;// 车辆过滤信息
        stInStartFind.stPersonInfoEx2.stuTrafficCarAttribute[0].nCategoryArrayNums = 1;
        stInStartFind.stPersonInfoEx2.stuTrafficCarAttribute[0].emCategoryArray[0] = NetSDKLib.EM_NET_VEHICLE_TYPE.NET_VEHICLE_TYPE_MICROBUS;// 面包车
        stInStartFind.stPersonInfoEx2.stuTrafficCarAttribute[0].nAnnualInspection = 2;//是否有年检标, 0: 不限  1: 无  2: 有
        stInStartFind.stPersonInfoEx2.stuTrafficCarAttribute[0].nVehicleColorArrayNums = 1;
        stInStartFind.stPersonInfoEx2.stuTrafficCarAttribute[0].emVehicleColorArray[0] = EM_OBJECT_COLOR_TYPE.EM_OBJECT_COLOR_TYPE_WHITE;
        // 让设备根据查询条件整理结果集
        NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX stOutParam = new NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX();
        stInStartFind.write();
        stOutParam.write();
        if (netsdk.CLIENT_StartMultiFindFaceRecognitionEx(m_hLoginHandle, stInStartFind.getPointer(),
                stOutParam.getPointer(), 3000)) {
            stOutParam.read();
            System.out.println("CLIENT_StartMultiFindFaceRecognitionEx success, count = " + stOutParam.nTotalCount);
            NetSDKLib.LLong findHandle = stOutParam.lFindHandle;
            if (stOutParam.nTotalCount == -1) { // -1表示总条数未生成,要推迟获取, 使用CLIENT_AttachFaceFindState接口状态
                nToken = stOutParam.nToken;
                // 入参
                NetSDKLib.NET_IN_FACE_FIND_STATE pstInParam = new NetSDKLib.NET_IN_FACE_FIND_STATE();
                pstInParam.nTokenNum = 1;
                pstInParam.nTokens = new IntByReference(nToken); // 查询令牌
                pstInParam.cbFaceFindState = DefaultFaceFindStateCallback.getInstance();
 
                // 出参
                NetSDKLib.NET_OUT_FACE_FIND_STATE pstOutParam = new NetSDKLib.NET_OUT_FACE_FIND_STATE();
                pstInParam.write();
                NetSDKLib.LLong attachFaceHandle = netsdk.CLIENT_AttachFaceFindState(m_hLoginHandle, pstInParam,
                        pstOutParam, 4000);
                pstInParam.read();
                if (attachFaceHandle.longValue() != 0) {
                    System.out.println("AttachFaceFindState Succeed!");
                }
                // 等待进度完成
                try {
                    while (DefaultFaceFindStateCallback.getInstance().getProgress(m_hLoginHandle.longValue(),
                            attachFaceHandle.longValue(), nToken) < 100) {
                    }
                    // 进度到100,有数据了默认查个10条
                    doFindSearchByVechilePictureEx(findHandle, 10, 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                doFindSearchByVechilePictureEx(findHandle,10,stOutParam.nTotalCount);
            }
        } else {
            System.out.println("CLIENT_StartMultiFindFaceRecognitionEx Failed, Error:" + ToolKits.getErrorCode());
        }
    }
    
        
    /**
     *  机动车以图搜图
     * @param longHandle CLIENT_StartFindFaceRecognition 接口返回的查询句柄
     * @param count      查询的个数
     */
    public void doFindSearchByVechilePictureEx(NetSDKLib.LLong findHandle, int count,int nTotalCount) {
        int doNextCount = 0;
        // 分页查找数据
        NET_IN_DOFIND_FACERECONGNITION_EX stFindIn = new NET_IN_DOFIND_FACERECONGNITION_EX();
        stFindIn.lFindHandle = findHandle;
        stFindIn.nCount = 10; // 当前想查询的记录条数
        stFindIn.nBeginNum = 0; // 每次递增
        int index =0;
        NET_OUT_DOFIND_FACERECONGNITION_EX stFindOut = new NET_OUT_DOFIND_FACERECONGNITION_EX();
        stFindOut.nCadidateEx2Num = count;
 
        NET_CANDIDATE_INFOEX2[] tmp = new NET_CANDIDATE_INFOEX2[count];
        for (int i = 0; i < count; i++) {
            tmp[i] = new NET_CANDIDATE_INFOEX2();
        }
        stFindOut.nBufferLen = tmp[0].size() * count;
        stFindOut.pBuffer = new Memory(tmp[0].size() * count);
        stFindOut.pBuffer.clear(tmp[0].size() * count);
        for (int i = 0; i < count; i++) {
            tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].nFilePathLen = 256;
            tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].pszFilePath = new Memory(256);
        }
        stFindOut.pstuCandidatesEx2 = new Memory(tmp[0].size() * count); // Pointer初始化
        stFindOut.pstuCandidatesEx2.clear(tmp[0].size() * count);
 
        ToolKits.SetStructArrToPointerData(tmp, stFindOut.pstuCandidatesEx2); // 将数组内存拷贝给 Pointer
 
        do {
            stFindIn.write();
            stFindOut.write();
            if (netsdk.CLIENT_DoFindFaceRecognitionEx(stFindIn.getPointer(), stFindOut.getPointer(), 1000)) {
                System.out.println("CLIENT_DoFindFaceRecognitionEx Succeed");
                stFindOut.read();
                ToolKits.GetPointerDataToStructArr(stFindOut.pstuCandidatesEx2, tmp);
                System.out.println("设备实际返回的候选信息结构体个数: " + stFindOut.nRetCadidateEx2Num);
                if (stFindOut.nRetCadidateEx2Num == 0) {
                    System.out.println("没有查询到相关数据");
                    break;
                }
                try {
                    for (int i = 0; i < stFindOut.nRetCadidateEx2Num; i++) {
                        index = i + doNextCount * count; // 查询的总个数 - 1, 从0开始                            
                        System.out.println("szVehicleColor: "+ new String(tmp[i].stuHistoryTrafficCarInfo.szVehicleColor, encode));
                        System.out.println("szPlateNumber: " + new String(tmp[i].stuHistoryTrafficCarInfo.szPlateNumber, encode));
 
                    }
                        
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("CLIENT_DoFindFaceRecognitionEx Failed, Error:" + ENUMERROR.getErrorMessage());
                break;
            }
 
            if (stFindOut.nRetCadidateEx2Num < stFindIn.nCount|| index == (nTotalCount-1)) {
                System.out.println("没有更多数据,结束查询");
                break;
            } else {
                stFindIn.nBeginNum += count;
                doNextCount++;
            }
        } while (true);
        netsdk.CLIENT_StopFindFaceRecognition(findHandle);
    }
    
 
    /**
     * 人脸以图搜图(注册库)
     */
    public void searchByFacePictureBlockListMultiVer() {
        searchByFacePictureBlockList("2023-08-17", "2023-08-18", "50");
    }
 
    /**
     * 人脸以图搜图(注册库)
     * 
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param chn       通道号
     * @param similary  相似度
     * @param memory    图片缓存
     * @param nPicLen   图片大小
     */
    public void searchByFacePictureBlockList(String startTime, String endTime,  String similary) {
        String[] startTimeStr = startTime.split("-");
        String[] endTimeStr = endTime.split("-");
        NET_IN_STARTMULTIFIND_FACERECONGNITION_EX stInStartFind = new NET_IN_STARTMULTIFIND_FACERECONGNITION_EX();
            
        stInStartFind.emObjectType = NetSDKLib.EM_OBJECT_TYPE.EM_OBJECT_TYPE_FACE;
        // 相似度
        if (!similary.equals("")) {
            stInStartFind.stMatchOptions.nSimilarity = Integer.parseInt(similary);//相似度
            stInStartFind.stMatchOptions.nMaxCandidate = 1000;//报告的最大候选个数(根据相似度进行排序,取相似度最大的候选人数报告)
        }
        
        stInStartFind.stFilterInfo.nGroupIdNum = 1;
        String nGroupId = "3";
        System.arraycopy(nGroupId.getBytes(), 0, stInStartFind.stFilterInfo.szGroupIdArr[0].szGroupId, 0, nGroupId.getBytes().length);
        stInStartFind.stFilterInfo.nRangeNum = 1;
        stInStartFind.stFilterInfo.szRange[0] = NetSDKLib.EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_BLACKLIST; // 禁止名单数据库(现在用作注册库)
        stInStartFind.stFilterInfo.stStartTime.dwYear = Integer.parseInt(startTimeStr[0]);
        stInStartFind.stFilterInfo.stStartTime.dwMonth = Integer.parseInt(startTimeStr[1]);
        stInStartFind.stFilterInfo.stStartTime.dwDay = Integer.parseInt(startTimeStr[2]);
        stInStartFind.stFilterInfo.stEndTime.dwYear = Integer.parseInt(endTimeStr[0]);
        stInStartFind.stFilterInfo.stEndTime.dwMonth = Integer.parseInt(endTimeStr[1]);
        stInStartFind.stFilterInfo.stEndTime.dwDay = Integer.parseInt(endTimeStr[2]);
 
        // 图片信息
        String picPath = "D:\\297.jpg";
        byte[] picBuf = ToolKits.readPictureToByteArray(picPath);
        stInStartFind.bPersonEx2Enable = 1; // 人员信息查询条件是否有效, 并使用扩展结构体
        stInStartFind.stPersonInfoEx2.bPersonExEnable = 1;
        stInStartFind.stPersonInfoEx2.stPersonInfoEx.wFacePicNum = 1;
        stInStartFind.stPersonInfoEx2.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;
        stInStartFind.stPersonInfoEx2.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = picBuf.length;
        stInStartFind.pBuffer = new Memory(picBuf.length);
        stInStartFind.pBuffer.write(0, picBuf, 0, picBuf.length);
        stInStartFind.nBufferLen = picBuf.length;
 
        // 让设备根据查询条件整理结果集
        NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX stOutParam = new NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX();
        stInStartFind.write();
        stOutParam.write();
        if (netsdk.CLIENT_StartMultiFindFaceRecognitionEx(m_hLoginHandle, stInStartFind.getPointer(),
                stOutParam.getPointer(), 3000)) {
            stOutParam.read();
            System.out.println("CLIENT_StartMultiFindFaceRecognitionEx success, count = " + stOutParam.nTotalCount);
            NetSDKLib.LLong findHandle = stOutParam.lFindHandle;
            if (stOutParam.nTotalCount == -1) { // -1表示总条数未生成,要推迟获取, 使用CLIENT_AttachFaceFindState接口状态
                nToken = stOutParam.nToken;
                // 入参
                NetSDKLib.NET_IN_FACE_FIND_STATE pstInParam = new NetSDKLib.NET_IN_FACE_FIND_STATE();
                pstInParam.nTokenNum = 1;
                pstInParam.nTokens = new IntByReference(nToken); // 查询令牌
                pstInParam.cbFaceFindState = DefaultFaceFindStateCallback.getInstance();
 
                // 出参
                NetSDKLib.NET_OUT_FACE_FIND_STATE pstOutParam = new NetSDKLib.NET_OUT_FACE_FIND_STATE();
                pstInParam.write();
                NetSDKLib.LLong attachFaceHandle = netsdk.CLIENT_AttachFaceFindState(m_hLoginHandle, pstInParam,
                        pstOutParam, 4000);
                pstInParam.read();
                if (attachFaceHandle.longValue() != 0) {
                    System.out.println("AttachFaceFindState Succeed!");
                }
                // 等待进度完成
                try {
                    while (DefaultFaceFindStateCallback.getInstance().getProgress(m_hLoginHandle.longValue(),
                            attachFaceHandle.longValue(), nToken) < 100) {
                    }
                    // 进度到100,有数据了默认查个10条
                    doFindSearchByFacePictureBlockList(findHandle, 10, 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                //查询已有的所有
                doFindSearchByFacePictureBlockList(findHandle, 10,stOutParam.nTotalCount);
            }
        } else {
            System.out.println("CLIENT_StartMultiFindFaceRecognitionEx Failed, Error:" + ToolKits.getErrorCode());
        }
    }
    
        
    /**
     *  人脸以图搜图(注册库)
     * @param longHandle CLIENT_StartFindFaceRecognition 接口返回的查询句柄
     * @param count      查询的个数
     */
    public void doFindSearchByFacePictureBlockList(NetSDKLib.LLong findHandle, int count,int nTotalCount) {
        int doNextCount = 0;
        // 分页查找数据
        NET_IN_DOFIND_FACERECONGNITION_EX stFindIn = new NET_IN_DOFIND_FACERECONGNITION_EX();
        stFindIn.lFindHandle = findHandle;
        stFindIn.emDataType = EM_NEEDED_PIC_RETURN_TYPE.EM_NEEDED_PIC_TYPE_HTTP_URL.getType();
        stFindIn.nCount = 10; // 当前想查询的记录条数
        stFindIn.nBeginNum = 0; // 每次递增
        int index = 0; //总计
 
        NET_OUT_DOFIND_FACERECONGNITION_EX stFindOut = new NET_OUT_DOFIND_FACERECONGNITION_EX();
        stFindOut.nCadidateEx2Num = count;
 
        NET_CANDIDATE_INFOEX2[] tmp = new NET_CANDIDATE_INFOEX2[count];
        for (int i = 0; i < count; i++) {
            tmp[i] = new NET_CANDIDATE_INFOEX2();
        }
        stFindOut.nBufferLen = tmp[0].size() * count;
        stFindOut.pBuffer = new Memory(tmp[0].size() * count);
        stFindOut.pBuffer.clear(tmp[0].size() * count);
        for (int i = 0; i < count; i++) {
            tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].nFilePathLen = 256;
            tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].pszFilePath = new Memory(256);
        }
        stFindOut.pstuCandidatesEx2 = new Memory(tmp[0].size() * count); // Pointer初始化
        stFindOut.pstuCandidatesEx2.clear(tmp[0].size() * count);
 
        ToolKits.SetStructArrToPointerData(tmp, stFindOut.pstuCandidatesEx2); // 将数组内存拷贝给 Pointer
 
        do {
            
            stFindIn.write();
            stFindOut.write();
            if (netsdk.CLIENT_DoFindFaceRecognitionEx(stFindIn.getPointer(), stFindOut.getPointer(), 1000)) {
                System.out.println("CLIENT_DoFindFaceRecognitionEx Succeed");
                stFindOut.read();
                ToolKits.GetPointerDataToStructArr(stFindOut.pstuCandidatesEx2, tmp);
                System.out.println("设备实际返回的候选信息结构体个数: " + stFindOut.nRetCadidateEx2Num);
                if (stFindOut.nRetCadidateEx2Num == 0) {
                    System.out.println("没有查询到相关数据");
                    break;
                }
                try {
                    for (int i = 0; i < stFindOut.nRetCadidateEx2Num; i++) {
                        index = i + doNextCount * count; // 查询的总个数 - 1, 从0开始        
                        //System.out.println("index: "+index);
                        System.out.println("姓名: "+ new String(tmp[i].stuCandidatesEx.stPersonInfo.szPersonName, encode));
                        System.out.println("性别: " +tmp[i].stuCandidatesEx.stPersonInfo.bySex);
                        System.out.println("PicURL: " +tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].pszFilePath.getString(0));
                    }
                        
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("CLIENT_DoFindFaceRecognitionEx Failed, Error:" + ENUMERROR.getErrorMessage());
                break;
            }
 
            if (stFindOut.nRetCadidateEx2Num < stFindIn.nCount || index == (nTotalCount-1)) {
                System.out.println("没有更多数据,结束查询");
                break;
            } else {
                stFindIn.nBeginNum += count;
                System.out.println("stFindIn.nBeginNum: "+stFindIn.nBeginNum);
                doNextCount++;
            }
        } while (true);
        netsdk.CLIENT_StopFindFaceRecognition(findHandle);
    }
 
    /**
     * 人脸以图搜图(抓拍库)
     */
    public void searchByFacePictureHistoryMultiVer() {
        searchByFacePictureHistory("2023-08-17", "2023-08-18", "50");
    }
 
    /**
     * 人脸以图搜图(抓拍库)
     * 
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param chn       通道号
     * @param similary  相似度
     * @param memory    图片缓存
     * @param nPicLen   图片大小
     */
    public void searchByFacePictureHistory(String startTime, String endTime,  String similary) {
        String[] startTimeStr = startTime.split("-");
        String[] endTimeStr = endTime.split("-");
        NET_IN_STARTMULTIFIND_FACERECONGNITION_EX stInStartFind = new NET_IN_STARTMULTIFIND_FACERECONGNITION_EX();
            
        // 通道号
        stInStartFind.nChannelCount = 4;
        IntPoint[] intPoints = new IntPoint[4];
        for (int i = 0; i < 4; i++) {
            intPoints[i] = new IntPoint(i);
        }
        stInStartFind.pChannelID = new Memory(intPoints[0].size() * stInStartFind.nChannelCount);
        stInStartFind.pChannelID.clear(intPoints[0].size() * stInStartFind.nChannelCount);
        ToolKits.SetStructArrToPointerData(intPoints, stInStartFind.pChannelID);
        stInStartFind.emObjectType = NetSDKLib.EM_OBJECT_TYPE.EM_OBJECT_TYPE_FACE;
        // 相似度
        if (!similary.equals("")) {
            stInStartFind.stMatchOptions.nSimilarity = Integer.parseInt(similary);//相似度
            stInStartFind.stMatchOptions.nMaxCandidate = 1000;//报告的最大候选个数(根据相似度进行排序,取相似度最大的候选人数报告)
        }
        
        stInStartFind.stFilterInfo.nRangeNum = 1;
        stInStartFind.stFilterInfo.szRange[0] = NetSDKLib.EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_HISTORY; // 历史数据库
        stInStartFind.stFilterInfo.stStartTime.dwYear = Integer.parseInt(startTimeStr[0]);
        stInStartFind.stFilterInfo.stStartTime.dwMonth = Integer.parseInt(startTimeStr[1]);
        stInStartFind.stFilterInfo.stStartTime.dwDay = Integer.parseInt(startTimeStr[2]);
        stInStartFind.stFilterInfo.stEndTime.dwYear = Integer.parseInt(endTimeStr[0]);
        stInStartFind.stFilterInfo.stEndTime.dwMonth = Integer.parseInt(endTimeStr[1]);
        stInStartFind.stFilterInfo.stEndTime.dwDay = Integer.parseInt(endTimeStr[2]);
 
        // 图片信息
        String picPath = "D:\\297.jpg";
        byte[] picBuf = ToolKits.readPictureToByteArray(picPath);
        stInStartFind.bPersonEx2Enable = 1; // 人员信息查询条件是否有效, 并使用扩展结构体
        stInStartFind.stPersonInfoEx2.bPersonExEnable = 1;
        stInStartFind.stPersonInfoEx2.stPersonInfoEx.wFacePicNum = 1;
        stInStartFind.stPersonInfoEx2.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;
        stInStartFind.stPersonInfoEx2.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = picBuf.length;
        stInStartFind.pBuffer = new Memory(picBuf.length);
        stInStartFind.pBuffer.write(0, picBuf, 0, picBuf.length);
        stInStartFind.nBufferLen = picBuf.length;
 
        // 让设备根据查询条件整理结果集
        NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX stOutParam = new NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX();
        stInStartFind.write();
        stOutParam.write();
        if (netsdk.CLIENT_StartMultiFindFaceRecognitionEx(m_hLoginHandle, stInStartFind.getPointer(),
                stOutParam.getPointer(), 3000)) {
            stOutParam.read();
            System.out.println("CLIENT_StartMultiFindFaceRecognitionEx success, count = " + stOutParam.nTotalCount);
            NetSDKLib.LLong findHandle = stOutParam.lFindHandle;
            if (stOutParam.nTotalCount == -1) { // -1表示总条数未生成,要推迟获取, 使用CLIENT_AttachFaceFindState接口状态
                nToken = stOutParam.nToken;
                // 入参
                NetSDKLib.NET_IN_FACE_FIND_STATE pstInParam = new NetSDKLib.NET_IN_FACE_FIND_STATE();
                pstInParam.nTokenNum = 1;
                pstInParam.nTokens = new IntByReference(nToken); // 查询令牌
                pstInParam.cbFaceFindState = DefaultFaceFindStateCallback.getInstance();
 
                // 出参
                NetSDKLib.NET_OUT_FACE_FIND_STATE pstOutParam = new NetSDKLib.NET_OUT_FACE_FIND_STATE();
                pstInParam.write();
                NetSDKLib.LLong attachFaceHandle = netsdk.CLIENT_AttachFaceFindState(m_hLoginHandle, pstInParam,
                        pstOutParam, 4000);
                pstInParam.read();
                if (attachFaceHandle.longValue() != 0) {
                    System.out.println("AttachFaceFindState Succeed!");
                }
                // 等待进度完成
                try {
                    while (DefaultFaceFindStateCallback.getInstance().getProgress(m_hLoginHandle.longValue(),
                            attachFaceHandle.longValue(), nToken) < 100) {
                    }
                    // 进度到100,有数据了默认查个10条
                    doFindSearchByFacePictureHistory(findHandle, 10, 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                //查询已有的所有
                doFindSearchByFacePictureHistory(findHandle, 10,stOutParam.nTotalCount);
            }
        } else {
            System.out.println("CLIENT_StartMultiFindFaceRecognitionEx Failed, Error:" + ToolKits.getErrorCode());
        }
    }
    
        
    /**
     *  人脸以图搜图(抓拍库)
     * @param longHandle CLIENT_StartFindFaceRecognition 接口返回的查询句柄
     * @param count      查询的个数
     */
    public void doFindSearchByFacePictureHistory(NetSDKLib.LLong findHandle, int count,int nTotalCount) {
        int doNextCount = 0;
        // 分页查找数据
        NET_IN_DOFIND_FACERECONGNITION_EX stFindIn = new NET_IN_DOFIND_FACERECONGNITION_EX();
        stFindIn.lFindHandle = findHandle;
        stFindIn.emDataType = EM_NEEDED_PIC_RETURN_TYPE.EM_NEEDED_PIC_TYPE_HTTP_URL.getType();
        stFindIn.nCount = 10; // 当前想查询的记录条数
        stFindIn.nBeginNum = 0; // 每次递增
        int index = 0; //总计
 
        NET_OUT_DOFIND_FACERECONGNITION_EX stFindOut = new NET_OUT_DOFIND_FACERECONGNITION_EX();
        stFindOut.nCadidateEx2Num = count;
 
        NET_CANDIDATE_INFOEX2[] tmp = new NET_CANDIDATE_INFOEX2[count];
        for (int i = 0; i < count; i++) {
            tmp[i] = new NET_CANDIDATE_INFOEX2();
        }
        stFindOut.nBufferLen = tmp[0].size() * count;
        stFindOut.pBuffer = new Memory(tmp[0].size() * count);
        stFindOut.pBuffer.clear(tmp[0].size() * count);
        for (int i = 0; i < count; i++) {
            tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].nFilePathLen = 256;
            tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].pszFilePath = new Memory(256);
        }
        stFindOut.pstuCandidatesEx2 = new Memory(tmp[0].size() * count); // Pointer初始化
        stFindOut.pstuCandidatesEx2.clear(tmp[0].size() * count);
 
        ToolKits.SetStructArrToPointerData(tmp, stFindOut.pstuCandidatesEx2); // 将数组内存拷贝给 Pointer
 
        do {
            
            stFindIn.write();
            stFindOut.write();
            if (netsdk.CLIENT_DoFindFaceRecognitionEx(stFindIn.getPointer(), stFindOut.getPointer(), 1000)) {
                System.out.println("CLIENT_DoFindFaceRecognitionEx Succeed");
                stFindOut.read();
                ToolKits.GetPointerDataToStructArr(stFindOut.pstuCandidatesEx2, tmp);
                System.out.println("设备实际返回的候选信息结构体个数: " + stFindOut.nRetCadidateEx2Num);
                if (stFindOut.nRetCadidateEx2Num == 0) {
                    System.out.println("没有查询到相关数据");
                    break;
                }
                try {
                    for (int i = 0; i < stFindOut.nRetCadidateEx2Num; i++) {
                        index = i + doNextCount * count; // 查询的总个数 - 1, 从0开始        
                        //System.out.println("index: "+index);
                        System.out.println("姓名: "+ new String(tmp[i].stuCandidatesEx.stPersonInfo.szPersonName, encode));
                        System.out.println("性别: " +tmp[i].stuCandidatesEx.stPersonInfo.bySex);
                        System.out.println("PicURL: " +tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].pszFilePath.getString(0));
                    }
                        
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("CLIENT_DoFindFaceRecognitionEx Failed, Error:" + ENUMERROR.getErrorMessage());
                break;
            }
 
            if (stFindOut.nRetCadidateEx2Num < stFindIn.nCount || index == (nTotalCount-1)) {
                System.out.println("没有更多数据,结束查询");
                break;
            } else {
                stFindIn.nBeginNum += count;
                System.out.println("stFindIn.nBeginNum: "+stFindIn.nBeginNum);
                doNextCount++;
            }
        } while (true);
        netsdk.CLIENT_StopFindFaceRecognition(findHandle);
    }
    
    
    /******************************** 测试控制台 ***************************************/
 
    // 配置登陆地址,端口,用户名,密码
    private String m_strIpAddr = "172.23.222.103";
    private int m_nPort = 37777;
    private String m_strUser = "admin";
    private String m_strPassword = "Admin123";
 
    public static void main(String[] args) {
        MC8000Demo demo = new MC8000Demo();
        demo.InitTest();
        demo.RunTest();
        demo.EndTest();
 
    }
 
    /**
     * 初始化测试
     */
    public void InitTest() {
        MC8000Demo.Init();
        this.loginWithHighLevel();
    }
 
    /**
     * 加载测试内容
     */
    public void RunTest() {
        CaseMenu menu = new CaseMenu();
        // 一、设备、通道信息获取
        menu.addItem(new CaseMenu.Item(this, "获取已添加的设备信息", "getAllDeviceInfo"));
        menu.addItem(new CaseMenu.Item(this, "获取设备通道信息", "getChannelInfo"));
        menu.addItem(new CaseMenu.Item(this, "设备、通道信息一起获取", "getDeviceInfoEx"));
 
        // 二、智能事件订阅
        menu.addItem(new CaseMenu.Item(this, "选择通道", "setChannelID"));
        menu.addItem(new CaseMenu.Item(this, "订阅智能事件", "AttachEventRealLoadPic"));
        menu.addItem(new CaseMenu.Item(this, "停止侦听智能事件", "DetachEventRealLoadPic"));
 
        // 三、人脸库查询
        menu.addItem(new CaseMenu.Item(this, "查询人脸库信息", "findGroupInfo"));    
        
        // 四、人脸库操作
        menu.addItem(new CaseMenu.Item(this, "添加人脸库", "addFaceRecognitionGroup"));
        menu.addItem(new CaseMenu.Item(this, "修改人脸库", "modifyFaceRecognitionGroup"));
        menu.addItem(new CaseMenu.Item(this, "删除人脸库", "deleteFaceRecognitionGroup"));
        
        // 五、人脸库成员操作
        menu.addItem(new CaseMenu.Item(this, "添加人员信息和人脸样", "addFaceRecognitionDB"));
        menu.addItem(new CaseMenu.Item(this, "修改人员信息和人脸样本", "modifyFaceRecognitionDB"));
        menu.addItem(new CaseMenu.Item(this, "删除人员信息和人脸样本", "delFaceRecognitionDB"));
        menu.addItem(new CaseMenu.Item(this, "通过UID删除人员信息和人脸样本", "delFaceRecognitionDBByUID"));
        
        // 十三、布控撤控 (前提需要设备先完成通道配置)
        menu.addItem(new CaseMenu.Item(this, "以人脸库的角度进行布控", "putFaceRecognitionDisposition"));
        menu.addItem(new CaseMenu.Item(this, "以人脸库的角度进行撤控", "delFaceRecognitionDisposition"));
                                                                        
        // 六、 图片检测
        menu.addItem(new CaseMenu.Item(this, "订阅检测结果", "attachDetectMultiFaceState"));
        menu.addItem(new CaseMenu.Item(this, "上传图片进行检测", "faceRecognitionDetectMultiFace"));
        menu.addItem(new CaseMenu.Item(this, "取消订阅", "detachDetectMultiFaceState"));
                
        // 七、人脸1v1
        menu.addItem(new CaseMenu.Item(this, "人脸1v1", "matchPicture"));
        
        // 八、人脸以图搜图(注册库)
        menu.addItem(new CaseMenu.Item(this, "人脸以图搜图(注册库)", "searchByFacePictureBlockListMultiVer"));                        
        
        // 九、人脸以图搜图(抓拍库)
        menu.addItem(new CaseMenu.Item(this, "人脸以图搜图(抓拍库)", "searchByFacePictureHistoryMultiVer"));            
        
        // 十二、机动车以图搜图
        menu.addItem(new CaseMenu.Item(this, "机动车以图搜图", "searchByVechilePictureMultiVer"));
 
        menu.run();
    }
 
    /**
     * 结束测试
     */
    public void EndTest() {
        System.out.println("End Test");
        this.logOut(); // 登出设备
        System.out.println("See You...");
        MC8000Demo.cleanAndExit(); // 清理资源并退出
    }
    /******************************** 结束 ***************************************/
}