package com.netsdk.module; import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.ToolKits; import com.netsdk.lib.Utils; import com.netsdk.lib.enumeration.EM_DATA_SOURCE_TYPE; import com.netsdk.lib.enumeration.ENUMERROR; import com.netsdk.lib.structure.NET_MATCH_TWO_FACE_IN; import com.netsdk.lib.structure.NET_MATCH_TWO_FACE_OUT; import com.netsdk.module.entity.AddAnalyseTaskResult; import com.netsdk.module.entity.ImageCompareInfo; import com.netsdk.module.entity.PushAnalysePictureInfo; import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.sun.jna.Structure; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.nio.charset.Charset; import java.util.List; /** * @author 47081 * @version 1.0 * @description 智能分析任务模块, 对智能分析任务相关接口进行二次封装, 方便调用 * @date 2020/10/19 */ public class AnalyseTaskModule extends BaseModule { public AnalyseTaskModule(NetSDKLib netSdkApi) { super(netSdkApi); } public AnalyseTaskModule() { super(); } /** * 1:1图片比对 * * @param originImage 原图片 * @param compareImage 需要对比的图片 * @param waitTime 超时时间,默认超时时间3000 * @return 相似度 0-100 */ public int matchImage(long loginHandler, InputStream originImage, InputStream compareImage, int waitTime) throws IOException { BufferedImage image = ImageIO.read(originImage); NET_MATCH_TWO_FACE_IN inParam = new NET_MATCH_TWO_FACE_IN(); ImageCompareInfo originInfo = readImage(image); //偏移量 inParam.stuOriginalImage.dwoffset = 0; inParam.stuOriginalImage.dwLength = originInfo.getLength(); inParam.stuOriginalImage.dwWidth = originInfo.getWidth(); inParam.stuOriginalImage.dwHeight = originInfo.getHeight(); image = ImageIO.read(compareImage); ImageCompareInfo compareInfo = readImage(image); //偏移量 inParam.stuCompareImage.dwoffset = originInfo.getLength(); inParam.stuCompareImage.dwLength = compareInfo.getLength(); inParam.stuCompareImage.dwHeight = compareInfo.getHeight(); inParam.stuCompareImage.dwWidth = compareInfo.getWidth(); //图片写入 inParam.pSendBuf = new Memory(originInfo.getLength() + compareInfo.getLength()); inParam.pSendBuf.write(0, originInfo.getData(), 0, originInfo.getLength()); inParam.pSendBuf.write(originInfo.getLength(), compareInfo.getData(), 0, compareInfo.getLength()); //下发的数据大小 inParam.dwSendBufLen = originInfo.getLength() + compareInfo.getLength(); NET_MATCH_TWO_FACE_OUT outParam = new NET_MATCH_TWO_FACE_OUT(); Pointer pInParam = new Memory(inParam.size()); ToolKits.SetStructDataToPointer(inParam, pInParam, 0); Pointer pOutParam = new Memory(outParam.size()); ToolKits.SetStructDataToPointer(outParam, pOutParam, 0); boolean result = getNetsdkApi().CLIENT_MatchTwoFaceImage(new NetSDKLib.LLong(loginHandler), pInParam, pOutParam, waitTime); if (!result) { System.out.println("match two image failed. error is " + ENUMERROR.getErrorMessage()); return 0; } ToolKits.GetPointerData(pOutParam, outParam); return outParam.nSimilarity; } /** * 读取图片信息 * * @param image 缓存的图片 * @return * @throws IOException */ private ImageCompareInfo readImage(BufferedImage image) { return readImage(image, "jpg"); } private ImageCompareInfo readImage(BufferedImage image, String format) { ImageCompareInfo info = null; try { info = new ImageCompareInfo(); info.setHeight(image.getHeight()); info.setWidth(image.getWidth()); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, format, outputStream); info.setData(outputStream.toByteArray()); info.setLength(outputStream.size()); } catch (IOException e) { e.printStackTrace(); } return info; } /** * 添加智能分析任务 * * @param loginHandler 登录句柄 * @param type 智能分析数据源类型{@link EM_DATA_SOURCE_TYPE} * @param inParam 输入参数,类型参考{@link EM_DATA_SOURCE_TYPE}所对应的结构体 * @param waitTime 超时时间 * @return 智能分析任务的结果 */ public AddAnalyseTaskResult addAnalyseTask(long loginHandler, EM_DATA_SOURCE_TYPE type, NetSDKLib.SdkStructure inParam, int waitTime) { Pointer pointer = new Memory(inParam.size()); ToolKits.SetStructDataToPointer(inParam, pointer, 0); NetSDKLib.NET_OUT_ADD_ANALYSE_TASK outParam = new NetSDKLib.NET_OUT_ADD_ANALYSE_TASK(); outParam.write(); boolean result = getNetsdkApi().CLIENT_AddAnalyseTask(new NetSDKLib.LLong(loginHandler), type.getType(), pointer, outParam, waitTime); AddAnalyseTaskResult taskResult = new AddAnalyseTaskResult(); taskResult.setResult(result); if (!result) { System.out.println("add analyseTask failed.error is " + ENUMERROR.getErrorMessage()); return taskResult; } outParam.read(); taskResult.setTaskId(outParam.nTaskID); taskResult.setVirtualChannel(outParam.nVirtualChannel); return taskResult; } /** * 启动智能分析任务 * * @param loginHandler 登录句柄 * @param taskId 任务id * @param waitTime 超时时间 * @return 任务是否启动成功 */ public boolean startAnalyseTask(long loginHandler, int taskId, int waitTime) { NetSDKLib.NET_IN_START_ANALYSE_TASK inParam = new NetSDKLib.NET_IN_START_ANALYSE_TASK(); inParam.nTaskID = taskId; NetSDKLib.NET_OUT_START_ANALYSE_TASK outParam = new NetSDKLib.NET_OUT_START_ANALYSE_TASK(); boolean result = getNetsdkApi().CLIENT_StartAnalyseTask(new NetSDKLib.LLong(loginHandler), inParam, outParam, waitTime); if (!result) { System.out.println("start analyse task failed.error is " + ENUMERROR.getErrorMessage()); } return result; } /** * 订阅智能分析任务 * * @param loginHandler 登录句柄 * @param taskIds 分析任务id数组 * @param filterAlarmTypes 过滤的事件类型 * @param isFilterImage 是否包含图片 * @param waitTime 超时时间 * @param callBack 智能分析的回调函数 * @param dwUser 自定义数据,不需要可传入null * @return 订阅句柄, 句柄为0表示订阅失败, 句柄不为0订阅成功 */ public long attachAnalyseTaskResult(long loginHandler, int[] taskIds, int[] filterAlarmTypes, boolean isFilterImage, NetSDKLib.fAnalyseTaskResultCallBack callBack, int waitTime, Structure dwUser) { //对数组长度进行校验 if (taskIds.length > NetSDKLib.MAX_ANALYSE_TASK_NUM) { System.out.println("taskIds's length is outOfBounds.please check"); return 0; } if (filterAlarmTypes.length > NetSDKLib.MAX_ANALYSE_FILTER_EVENT_NUM) { System.out.println("dwAlarms's length is outOfBounds.Please check."); return 0; } NetSDKLib.NET_IN_ATTACH_ANALYSE_RESULT inParam = new NetSDKLib.NET_IN_ATTACH_ANALYSE_RESULT(); //赋值 inParam.nTaskIdNum = taskIds.length; System.arraycopy(taskIds, 0, inParam.nTaskIDs, 0, taskIds.length); inParam.stuFilter.nEventNum = filterAlarmTypes.length; System.arraycopy(filterAlarmTypes, 0, inParam.stuFilter.dwAlarmTypes, 0, filterAlarmTypes.length); inParam.stuFilter.nImageDataFlag = isFilterImage ? 1 : 0; inParam.cbAnalyseTaskResult = callBack; if (dwUser != null) { inParam.dwUser = dwUser.getPointer(); } NetSDKLib.LLong attachHandler = getNetsdkApi().CLIENT_AttachAnalyseTaskResult(new NetSDKLib.LLong(loginHandler), inParam, waitTime); if (attachHandler.longValue() == 0) { System.out.println("attach analyseTask failed. error is " + ENUMERROR.getErrorMessage()); return 0; } return attachHandler.longValue(); } /** * 订阅智能分析任务 * * @param loginHandler 登录句柄 * @param taskIds 分析任务id * @param isFilterImage 是否包含图片 * @param callBack 订阅回调函数,建议写成单例模式 * @param waitTime 超时时间 * @param dwUser 自定义数据 * @return 订阅句柄, 句柄为0表示订阅失败, 不为0订阅成功 */ public long attachAnalyseTaskResult(long loginHandler, int[] taskIds, boolean isFilterImage, NetSDKLib.fAnalyseTaskResultCallBack callBack, int waitTime, Structure dwUser) { return attachAnalyseTaskResult(loginHandler, taskIds, new int[]{}, isFilterImage, callBack, waitTime, dwUser); } /** * 智能分析退订 * * @param attachHandler 订阅句柄 * @return 是否成功退订 */ public boolean detachAnalyseTaskResult(long attachHandler) { boolean result = getNetsdkApi().CLIENT_DetachAnalyseTaskResult(new NetSDKLib.LLong(attachHandler)); if (!result) { System.out.println("detach analyseTask result failed. error is " + ENUMERROR.getErrorMessage()); } return result; } ///////////////////////////推送图片有两种方式:文件的形式和远程url的方式,选择一种即可////////////////////////////// /** * @param type 推送图片还是url,1:图片文件,0:url * @param infos * @return */ public boolean pushAnalysePicture(long loginHandler, int taskId, int type, List infos, int waitTime) { if (type != 1 && type != 0) { System.out.println("wrong type.please check.type 1: pictures,0:url"); return false; } NetSDKLib.NET_IN_PUSH_ANALYSE_PICTURE_FILE inParam = new NetSDKLib.NET_IN_PUSH_ANALYSE_PICTURE_FILE(); if (infos.size() > inParam.stuPushPicInfos.length) { System.out.println("infos's length is outOfBounds in stuPushInfos."); } inParam.nTaskID = taskId; inParam.nPicNum = infos.size(); PushAnalysePictureInfo info = null; File file = null; int totalLength = 0; //推送图片 if (type == 1) { for (int i = 0; i < inParam.nPicNum; i++) { info = infos.get(i); byte[] fileId = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode())); System.arraycopy(fileId, 0, inParam.stuPushPicInfos[i].szFileID, 0, fileId.length); //inParam.stuPushPicInfos[i].szFileID = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode())); if (i == 0) { inParam.stuPushPicInfos[i].nOffset = 0; } else { inParam.stuPushPicInfos[i].nOffset = inParam.stuPushPicInfos[i - 1].nLength; } file = new File(info.getName()); inParam.stuPushPicInfos[i].nLength = (int) file.length(); totalLength += inParam.stuPushPicInfos[i].nLength; //stuXRayCustomInfo暂不赋值,自定义数据,xX光机专用 } inParam.nBinBufLen = totalLength; //写入图片到Pointer inParam.pBinBuf = new Memory(totalLength); byte[] data; int offset = 0; for (PushAnalysePictureInfo picture : infos) { try { FileInputStream inputStream = null; file = new File(picture.getName()); data = new byte[(int) file.length()]; inputStream = new FileInputStream(file); inputStream.read(data); inParam.pBinBuf.write(offset, data, 0, data.length); offset += data.length; inputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } else { //推送url for (int i = 0; i < infos.size(); i++) { info = infos.get(i); // inParam.stuPushPicInfos[i].szFileID = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode())); byte[] fileId = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode())); System.arraycopy(fileId, 0, inParam.stuPushPicInfos[i].szFileID, 0, fileId.length); // inParam.stuPushPicInfos[i].szUrl = info.getName().getBytes(Charset.forName(Utils.getPlatformEncode())); byte[] name = info.getName().getBytes(Charset.forName(Utils.getPlatformEncode())); System.arraycopy(name, 0, inParam.stuPushPicInfos[i].szUrl, 0, name.length); } } NetSDKLib.NET_OUT_PUSH_ANALYSE_PICTURE_FILE outParam = new NetSDKLib.NET_OUT_PUSH_ANALYSE_PICTURE_FILE(); boolean result = getNetsdkApi().CLIENT_PushAnalysePictureFile(new NetSDKLib.LLong(loginHandler), inParam, outParam, waitTime); if (!result) { System.out.println("push picture failed.error is " + ENUMERROR.getErrorMessage()); } return result; } /** * 删除(停止)智能分析任务 * * @param loginHandler 登录句柄 * @param taskId 智能任务id * @param waitTime 超时时间 * @return 删除分析任务是否成功 */ public boolean removeAnalyseTask(long loginHandler, int taskId, int waitTime) { NetSDKLib.NET_IN_REMOVE_ANALYSE_TASK inParam = new NetSDKLib.NET_IN_REMOVE_ANALYSE_TASK(); inParam.nTaskID = taskId; NetSDKLib.NET_OUT_REMOVE_ANALYSE_TASK outParam = new NetSDKLib.NET_OUT_REMOVE_ANALYSE_TASK(); boolean result = getNetsdkApi().CLIENT_RemoveAnalyseTask(new NetSDKLib.LLong(loginHandler), inParam, outParam, waitTime); if (!result) { System.out.println("remove analyseTask failed.error is " + ENUMERROR.getErrorMessage()); } return result; } }