大华JAVA SDK抓拍图片

本文介绍了一个名为 DHController 的 Java 类,该类通过 RESTful API 接口接收参数并实现从指定 IP 地址的设备上抓取图片的功能。文章详细展示了如何通过登录设备、发送抓拍命令及接收图片数据的过程。

DHController.java

@RestController
public class DHController {

    Logger logger = LoggerFactory.getLogger(DHController.class);

    @Autowired
    HttpServletRequest request;

    @RequestMapping(value = "/capture", method = RequestMethod.POST)
    public JsonResponse capture(@RequestBody Map<String, String> params) {
        JsonResponse jsonResponse;
        String key = null;
        NetSDKLib.LLong loginhandle = new NetSDKLib.LLong(0);
        try {
            String ip = params.get("ip");
            String port = params.get("port");
            String user = params.get("user");
            String password = params.get("password");
            String channel = params.get("channel");
            String filename = params.get("filename");
            boolean init = this.initClient();
            if (!init) {
                throw new Exception("客户端初始化失败");
            }
            CaptureReceiveCB captureReceiveCB = new CaptureReceiveCB(ip, filename);
            loginhandle = this.login(ip, Integer.parseInt(port), user, password, captureReceiveCB);
            if(loginhandle.longValue() == 0) {
                throw new Exception("登录失败,用户名或密码不正确");
            }
            boolean resultCapture = this.capture(loginhandle, Integer.parseInt(channel), captureReceiveCB);
            if(!resultCapture) {
                throw new Exception("抓拍图片失败");
            }
            key = ip + loginhandle.longValue();
            Semaphore semaphore = Cache.getSemaphore(key);
            semaphore.tryAcquire(1, 5, TimeUnit.SECONDS);
            String filepath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ request.getContextPath() + "/static/" + filename;
            jsonResponse = JsonResponse.success("抓拍图片成功", filepath);
        } catch (Exception e) {
            jsonResponse = JsonResponse.error("抓拍图片失败:" + e.getMessage());
            logger.error(e.getMessage(), e);
        }finally {
            if(key != null) {
                Cache.removeSemaphore(key);
            }
            if(loginhandle.longValue() != 0) {
                NetSDKLib.NETSDK_INSTANCE.CLIENT_Logout(loginhandle);
            }
            NetSDKLib.NETSDK_INSTANCE.CLIENT_Cleanup();
        }
        return jsonResponse;
    }

    private boolean initClient() {
        DisConnect disConnect = new DisConnect();
        return NetSDKLib.NETSDK_INSTANCE.CLIENT_Init(disConnect, null);
    }

    private NetSDKLib.LLong login(String ip, int port, String user, String password, CaptureReceiveCB captureReceiveCB) throws Exception {
        Native.setCallbackThreadInitializer(captureReceiveCB,
                new CallbackThreadInitializer(false, false, "snapPicture callback thread"));
        NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort = port;
        pstInParam.szIP = ip.getBytes();
        pstInParam.szPassword = password.getBytes();
        pstInParam.szUserName = user.getBytes();
        //出参
        NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
        NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo = m_stDeviceInfo;
        return NetSDKLib.NETSDK_INSTANCE.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
    }

    private boolean capture(NetSDKLib.LLong loginhandle, int channel, CaptureReceiveCB captureReceiveCB) throws Exception {
        NetSDKLib.NETSDK_INSTANCE.CLIENT_SetSnapRevCallBack(captureReceiveCB, null);
        // send caputre picture command to device
        NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS();
        stuSnapParams.Channel = channel;  			// channel
        stuSnapParams.mode = 0;    			// capture picture mode
        stuSnapParams.Quality = 3;				// picture quality
        stuSnapParams.InterSnap = 0; 	// timer capture picture time interval
        stuSnapParams.CmdSerial = 0;  			// request serial
        IntByReference reserved = new IntByReference(0);
        return NetSDKLib.NETSDK_INSTANCE.CLIENT_SnapPictureEx(loginhandle, stuSnapParams, reserved);
    }
}

CaptureReceiveCB.java

public class CaptureReceiveCB implements NetSDKLib.fSnapRev{

    Logger logger = LoggerFactory.getLogger(CaptureReceiveCB.class);

    String ip;

    private String filename;

    public CaptureReceiveCB(String ip, String filename) {
        this.ip = ip;
        this.filename = filename;
    }

    @Override
    public void invoke(NetSDKLib.LLong lLoginID, Pointer pBuf, int RevLen, int EncodeType, int CmdSerial, Pointer dwUser) {
        if(pBuf != null && RevLen > 0) {
            try {
                byte[] buf = pBuf.getByteArray(0, RevLen);
                ByteArrayInputStream byteArrInput = new ByteArrayInputStream(buf);
                BufferedImage bufferedImage = ImageIO.read(byteArrInput);
                if(bufferedImage == null) {
                    return;
                }
                String path = this.getClass().getResource("/").getPath() + "/static/" + filename;
                ImageIO.write(bufferedImage, "jpg", new File(path));
            } catch (IOException e) {
                logger.error("写文件失败:" + e.getMessage(), e);
            }finally {
                String key = ip + lLoginID.longValue();
                Semaphore semaphore = Cache.getSemaphore(key);
                semaphore.release();
            }
        }
    }
}

Cache.java

public class Cache {

    private static ConcurrentHashMap<String, Semaphore> semaphores = new ConcurrentHashMap<String, Semaphore>();

    public static Semaphore getSemaphore(String key) {
        Semaphore newSemaphore = new Semaphore(0);
        Semaphore semaphore = semaphores.putIfAbsent(key, newSemaphore);
        return semaphore == null ? newSemaphore : semaphore;
    }

    public static void removeSemaphore(String key) {
        semaphores.remove(key);
    }
}

DisConnect.java

public class DisConnect implements NetSDKLib.fDisConnect{

    Logger logger = LoggerFactory.getLogger(DisConnect.class);

    @Override
    public void invoke(NetSDKLib.LLong lLong, String s, int i, Pointer pointer) {
        logger.error("客户端失去连接");
    }
}
### 大华摄像头 SDK 使用教程 #### 安装与配置环境 为了使用大华摄像头SDK,需先下载对应版本的大华SDK包。通常该软件开发套件会包含详细的安装指南文档[^2]。 对于Windows操作系统而言,在完成解压后运行`setup.exe`文件按照提示逐步设置即可;而对于Linux系统,则需要依据官方提供的说明文档来进行编译和链接库的操作。确保环境中已正确安装依赖项如FFmpeg等多媒体处理工具[^3]。 #### 初始化设备连接 建立到摄像机的实际物理连接之后,下一步就是初始化逻辑上的通信链路: ```cpp #include "HCNetSDK.h" // 加载动态链接库并启动加载器 BOOL bInit = NET_DVR_Init(); if (!bInit){ printf("NET_DVR_Init Failed!\n"); } ``` 这段C++代码展示了如何调用`HCNetSDK.h`头文件中的函数来初始化SDK环境。如果返回值为假则表示初始化失败。 #### 登录设备获取句柄 成功初始化后就可以尝试登录目标设备了: ```cpp LONG lUserID; USER_LOGIN_INFO struLoginInfo={0}; struLoginInfo.bUseAsynLogin = 0; // 同步模式下设为0,异步模式下设为1. strcpy(struLoginInfo.sDeviceIP,"192.168.1.x"); strcpy(struLoginInfo.sUserName,"admin"); strcpy(struLoginInfo.sPassword,"password"); lUserID=NET_DVR_Login_V40(&struLoginInfo); if(lUserID<0){ printf("login error\n"); }else{ printf("login success\n"); } ``` 这里定义了一个结构体变量用于存储登陆所需的信息参数,并通过`NET_DVR_Login_V40()`方法传入这些数据以获得代表当前会话的对象ID。 #### 实现基本功能 一旦获得了有效的用户标识符(即上面提到的`lUserID`),便可以执行诸如预览、抓图等功能: ##### 开始实时预览 ```cpp CLIENT_PREVIEWINFO previewInfo ={0}; previewInfo.lChannel = 1 ; previewInfo.dwStreamType = STREAM_TYPE_MAIN ; previewInfo.bBlocked = TRUE ; int iHandle = NET_DVR_RealPlay_V40(lUserID,&previewInfo,NULL); if(iHandle >= 0 ) { printf ("Real Play Success \n") ; } else { printf ("Real Play Fail %d\n",NET_DVR_GetLastError()) ; } ``` 此部分实现了向指定通道请求开启实况播放的功能,其中包含了选择主码流还是子码流的选择选项。 ##### 抓拍图片保存至本地磁盘 ```cpp DWORD dwPicSize = 0; char* pBuf = NULL; NET_DVR_CapturePicture(lUserID, &dwPicSize); pBuf=(char*)malloc(dwPicSize); memset(pBuf,0,dwPicSize); NET_DVR_CapturePicture(lUserID,pBuf); FILE *fp=fopen("capture.jpg","wb+"); fwrite(pBuf,sizeof(char),dwPicSize,fp); fclose(fp); free(pBuf); ``` 上述代码片段描述了一种简单的方式去捕获来自远程相机的画面帧,并将其作为JPEG图像写入硬盘中。 #### 社区资源和技术支持渠道 除了官方的技术手册外,还有许多在线论坛可供开发者们交流心得经验。例如JavaCV社区就拥有活跃的技术讨论氛围,尽管主要围绕着计算机视觉领域展开话题,但对于涉及到音视频采集方面也有不少实用贴士[^4]。 另外值得注意的是,由于不同型号之间可能存在差异,因此建议优先查阅具体产品的API接口文档,以便更好地理解其特性及限制条件。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值