资讯动态

C#海康摄像头 SDK 调用代码

发布时间:2026/9/29 8:03:53 来源:尧图企业网站定制
一、整体功能架构说明1. 核心功能定位本代码基于海康威视 SDKCHCNetSDK实现摄像头基础操作涵盖 SDK 初始化、设备登录/退出、实时预览、云台控制上下左右、截图JPEG/BMP 格式、视频录像MP4格式及资源清理适配海康摄像头的常规监控场景实现全流程设备交互。2. 核心技术依赖海康 SDK基于 CHCNetSDK 封装的各类接口实现设备登录、预览、云台控制、截图、录像等核心操作是代码的核心依赖Windows 窗体通过 WinForms 控件实现参数输入、操作触发、结果展示适配桌面端监控管理场景文件操作基于 System.IO 命名空间实现截图、录像文件的路径生成与存储确保媒体文件正常落地异常处理通过错误码获取与弹窗提示实现操作异常的反馈提升交互体验资源管理通过 SDK 接口实现资源初始化与清理避免内存泄漏与资源占用3. 核心操作流程与参数核心流程SDK 初始化→设备登录→实时预览→云台控制/截图/录像→停止操作→退出登录→SDK 资源清理关键参数设备 IP、端口、用户名、密码登录必备通道号默认1、码流类型、链接模式预览必备文件存储路径截图/录像必备核心状态标识userID登录用户 ID唯一标识、irealHanlde预览句柄标识预览状态、isOpen录像状态标识二、代码逐行超细拆分解析1. 命名空间、全局变量与构造函数// 引入系统核心命名空间支撑 UI 控件、文件操作、编码等功能 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; // 引入海康 SDK 相关命名空间需提前导入 SDK 依赖 using WindowsFormsApp1; // 定义海康摄像头操作专属命名空间隔离代码层级避免类名冲突 namespace 海康摄像头 { /// summary /// 海康摄像头操作主界面类 /// 核心职责实现 SDK 初始化、设备登录/退出、实时预览、云台控制、截图、录像及资源清理 /// 核心特点基于海康 SDK 封装覆盖摄像头基础操作适配常规监控场景 /// /summary public partial class Form1 : Form { // 全局变量按功能分类各司其职保障操作状态与资源管理 // 1. SDK 初始化状态true-初始化成功false-初始化失败 public bool intSDK; // 2. 操作错误码存储 SDK 接口调用失败的错误码用于异常排查 public uint lastError; // 3. 登录用户 ID-1表示未登录非-1表示登录成功后的唯一用户标识 private int userID -1; // 4. 登录信息结构体存储设备 IP、端口、用户名、密码等登录参数 CHCNetSDK.NET_DVR_USER_LOGIN_INFO ploginInfo; // 5. 设备信息结构体存储登录成功后返回的设备相关信息 CHCNetSDK.NET_DVR_DEVICEINFO_V40 pDeviceInfo; // 6. 预览句柄-1表示未开启预览非-1表示预览状态用于停止预览、云台控制等操作 public int irealHanlde -1; // 7. 录像状态标识false-未录像true-正在录像 bool isOpen false; // 构造函数仅初始化界面控件Visual Studio 自动生成无需手动修改 public Form1() { InitializeComponent(); } // 后续事件方法拆分解析... } }说明全局变量设计贴合 SDK 操作逻辑状态标识与结构体分离清晰区分登录、预览、录像等核心状态便于后续操作的状态校验与资源管理。2. 窗体加载事件Form1_Load——SDK 初始化/// summary /// 窗体加载事件初始化海康 SDK为后续设备操作做准备 /// 核心逻辑调用 SDK 初始化接口判断初始化结果失败则获取错误码并提示 /// /summary private void Form1_Load(object sender, EventArgs e) { // 调用海康 SDK 初始化接口返回值为初始化状态 intSDK CHCNetSDK.NET_DVR_Init(); if (!intSDK) // 初始化失败 { // 获取 SDK 操作的最后一个错误码 lastError CHCNetSDK.NET_DVR_GetLastError(); // 可扩展将错误码写入日志文件便于后续排查代码中仅提示未实现日志写入 // 弹窗提示初始化失败及错误码 MessageBox.Show(初始化失败错误码 lastError); // 终止后续操作避免未初始化导致的接口调用异常 return; } }核心要点与易错点SDK 初始化优先级必须在所有设备操作登录、预览等前完成初始化否则所有 SDK 接口调用均会失败错误码获取初始化失败后需通过 NET_DVR_GetLastError 获取错误码便于定位失败原因如 SDK 未安装、依赖缺失等日志扩展代码中预留了日志写入注释实际项目可补充日志记录便于线上问题排查3. 登录/退出按钮事件button1_Click/// summary /// 设备登录/退出控制按钮点击事件 /// 切换逻辑未登录时执行登录流程已登录时执行退出流程 /// 核心流程校验参数→封装登录信息→调用登录接口→更新状态退出时释放资源→重置状态 /// /summary private void button1_Click(object sender, EventArgs e) { // 校验输入参数设备 IP、端口、用户名、密码不能为空 if (textBox1.Text || textBox2.Text || textBox3.Text||textBox4.Text) { MessageBox.Show(参数不能为空); return; } // 未登录状态执行登录流程 if (userID 0) { // 1. 封装登录信息结构体 ploginInfo new CHCNetSDK.NET_DVR_USER_LOGIN_INFO(); // 设备 IP转换为字节数组拷贝至登录信息结构体 byte[] ipbs Encoding.Default.GetBytes(textBox1.Text); ploginInfo.sDeviceAddress new byte[129]; ipbs.CopyTo(ploginInfo.sDeviceAddress, 0); // 用户名转换为字节数组拷贝至登录信息结构体 byte[] namebs Encoding.Default.GetBytes(textBox3.Text); ploginInfo.sUserName new byte[64]; namebs.CopyTo(ploginInfo.sUserName, 0); // 设备端口转换为 ushort 类型赋值给登录信息结构体 ploginInfo.wPort ushort.Parse(textBox2.Text); // 密码转换为字节数组拷贝至登录信息结构体 byte[] psbs Encoding.Default.GetBytes(textBox4.Text); ploginInfo.sPassword new byte[64]; psbs.CopyTo(ploginInfo.sPassword, 0); // 2. 初始化设备信息结构体用于接收登录返回的设备信息 pDeviceInfo new CHCNetSDK.NET_DVR_DEVICEINFO_V40(); // 3. 调用登录接口返回值为用户 ID≥0表示成功-1表示失败 userID CHCNetSDK.NET_DVR_Login_V40(ref ploginInfo, ref pDeviceInfo); if (userID 0) // 登录失败 { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(登录错误错误码 lastError); return; } else // 登录成功 { MessageBox.Show(登录成功); // 展示登录后的用户 ID label5.Text 登录的 UserID userID; // 更新按钮状态为“退出” button1.Text 退出; return; } } else // 已登录状态执行退出流程 { // 1. 调用退出登录接口 if (!CHCNetSDK.NET_DVR_Logout(userID)) { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(退出失败错误错误码 lastError); return; } // 2. 重置登录状态标识 userID -1; // 3. 停止预览若正在预览释放预览资源 if (!CHCNetSDK.NET_DVR_StopRealPlay(irealHanlde)) { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(退出预览失败错误错误码 lastError); return; } // 4. 重置预览状态标识 irealHanlde -1; // 5. 清空预览窗口 pictureBox1.Image null; // 6. 更新按钮状态为“登录” button2.Text 开始预览; button1.Text 登录; } }核心要点与易错点参数封装规范登录信息结构体中的字节数组需按 SDK 要求分配长度IP 129字节、用户名/密码64字节避免数组越界登录接口返回值用户 ID 具有唯一性后续所有设备操作预览、云台控制等均需通过该 ID 实现需妥善保存退出流程完整性退出登录时需同步停止预览、释放预览资源避免资源泄漏确保后续可重新登录参数校验登录前必须校验所有输入参数避免空参数导致的接口调用失败4. 预览/停止预览按钮事件button2_Click/// summary /// 实时预览/停止预览控制按钮点击事件 /// 切换逻辑未预览时开启预览已预览时停止预览 /// 核心流程校验登录状态→封装预览参数→调用预览接口→更新状态停止时释放预览资源→重置状态 /// /summary private void button2_Click(object sender, EventArgs e) { // 校验登录状态未登录无法开启预览 if (userID 0) { MessageBox.Show(请先登录再去预览); return; } // 未预览状态开启预览 if (irealHanlde 0) { // 1. 初始化预览参数结构体 CHCNetSDK.NET_DVR_PREVIEWINFO info new CHCNetSDK.NET_DVR_PREVIEWINFO(); // 通道号默认1需与设备实际通道号一致 info.lChannel 1; // 码流类型0-主码流高清预览1-子码流按需选择 info.dwStreamType 0; // 链接模式0-TCP 方式适配多数场景 info.dwLinkMode 0; // 预览窗口绑定 pictureBox 控件的句柄用于展示预览画面 info.hPlayWnd pictureBox1.Handle; // 阻塞模式true-阻塞取流直到播放完成才返回成功false-非阻塞取流 info.bBlocked true; // 缓存帧数设置播放缓冲区最大缓冲帧数优化播放流畅度 info.dwDisplayBufNum 1; // 2. 调用预览接口返回值为预览句柄≥0表示成功-1表示失败 IntPtr use new IntPtr(); irealHanlde CHCNetSDK.NET_DVR_RealPlay_V40(userID, ref info, null, IntPtr.Zero); if (irealHanlde 0) { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(打开预览失败错误错误码 lastError); return; } else { // 更新按钮状态为“停止预览” button2.Text 停止预览; } } else // 已预览状态停止预览 { // 调用停止预览接口 if (!CHCNetSDK.NET_DVR_StopRealPlay(irealHanlde)) { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(退出预览失败错误错误码 lastError); return; } // 重置预览状态标识 irealHanlde -1; // 更新按钮状态为“开始预览” button2.Text 开始预览; } }核心要点与易错点预览参数适配通道号、码流类型、链接模式需与设备实际配置一致否则会导致预览失败窗口句柄绑定预览窗口必须绑定控件句柄pictureBox1.Handle否则无法正常展示预览画面阻塞模式选择阻塞模式适合对播放稳定性要求高的场景非阻塞模式适合循环播放等场景按需选择预览句柄作用预览句柄是后续停止预览、云台控制、截图等操作的核心标识需妥善保存5. 云台控制按钮事件button3-button61. 左转按钮button3/// summary /// 云台左转按钮按下事件触发左转操作 /// /summary private void button3_MouseDown(object sender, MouseEventArgs e) { // 未预览时提示先预览 if (realPlayHandle 0) { MessageBox.Show(请先开启预览再控制摄像头云台); return; } // 按下开始左转参数30-开始1-停止速度2 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.PAN_LEFT, 0, 2); } private void button3_MouseUp(object sender, MouseEventArgs e) { // 松开停止左转 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.PAN_LEFT, 1, 2); }2. 右转按钮button4private void button4_MouseDown(object sender, MouseEventArgs e) { if (realPlayHandle 0) { MessageBox.Show(请先开启预览再控制摄像头云台); return; } // 按下开始右转 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.PAN_RIGHT, 0, 2); } private void button4_MouseUp(object sender, MouseEventArgs e) { // 松开停止右转 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.PAN_RIGHT, 1, 2); }3. 上仰按钮button5private void button5_MouseDown(object sender, MouseEventArgs e) { if (realPlayHandle 0) { MessageBox.Show(请先开启预览再控制摄像头云台); return; } // 按下开始上仰 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.TILT_UP, 0, 2); } private void button5_MouseUp(object sender, MouseEventArgs e) { // 松开停止上仰 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.TILT_UP, 1, 2); }4. 下俯按钮button6private void button6_MouseDown(object sender, MouseEventArgs e) { if (realPlayHandle 0) { MessageBox.Show(请先开启预览再控制摄像头云台); return; } // 按下开始下俯 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.TILT_DOWN, 0, 2); } private void button6_MouseUp(object sender, MouseEventArgs e) { // 松开停止下俯 CHCNetSDK.NET_DVR_PTZControlWithSpeed(realPlayHandle, CHCNetSDK.TILT_DOWN, 1, 2); }核心要点与易错点操作前提云台控制必须在预览开启后执行未预览时无法调用云台控制接口接口参数规范第二个参数为云台控制方向PAN_LEFT-左转、PAN_RIGHT-右转、TILT_UP-上仰、TILT_DOWN-下俯第三个参数为控制状态0-开始、1-停止第四个参数为控制速度事件绑定采用 MouseDown按下开始控制 MouseUp松开停止控制的方式实现云台的持续控制与精准停止符合用户操作习惯/// summary /// 截图按钮点击事件支持 JPEG、BMP 两种格式截图 /// 核心逻辑校验预览状态→生成存储路径→封装截图参数→调用截图接口→提示结果 /// /summary private void button7_Click(object sender, EventArgs e) { // 校验预览状态未预览无法进行截图 if (irealHanlde 0) { MessageBox.Show(请先预览再去抓图); return; } // JPEG 格式截图 if (radioButton1.Checked) { // 生成 JPEG 存储路径当前目录/image/时间戳.jpeg string imagePath Directory.GetCurrentDirectory() /image/ ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds().jpeg; // 初始化 JPEG 截图参数结构体 CHCNetSDK.NET_DVR_JPEGPARA jpeg new CHCNetSDK.NET_DVR_JPEGPARA(); // 图片尺寸0xff表示默认尺寸可按需调整 jpeg.wPicSize 0xff; // 图片质量0-最高质量数值越大质量越低 jpeg.wPicQuality 0; // 调用 JPEG 截图接口参数为用户 ID、通道号、截图参数、存储路径 int channel 1; if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(userID, channel, ref jpeg, imagePath)) { // 截图失败获取错误码并提示 lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(抓图 jpg 失败 错误码 lastError); return; } else { MessageBox.Show(存储成功); } } else // BMP 格式截图 { // 生成 BMP 存储路径当前目录/image/时间戳.bmp string imagePath Directory.GetCurrentDirectory() /image/ ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds() .bmp; // 调用 BMP 截图接口参数为预览句柄、存储路径 if (!CHCNetSDK.NET_DVR_CapturePicture(irealHanlde, imagePath)) { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(抓图 bmp 失败 错误码 lastError); return; } else { MessageBox.Show(存储 bmp 成功); } } }核心要点与易错点路径合法性截图存储路径需确保目录存在代码中未创建 image 目录需手动创建或补充目录创建逻辑否则会导致截图失败格式差异JPEG 截图需封装截图参数尺寸、质量BMP 截图直接通过预览句柄实现接口调用方式不同通道号一致性截图接口中的通道号需与预览通道号一致确保截取当前预览画面7. 录像按钮事件button8_Click/// summary /// 录像/停止录像按钮点击事件 /// 切换逻辑未录像时开启录像已录像时停止录像 /// 核心流程校验预览状态→生成存储路径→调用录像接口→更新状态停止时释放录像资源→重置状态 /// /summary private void button8_Click(object sender, EventArgs e) { // 生成 MP4存储路径当前目录/video/时间戳.mp4 string MP4Path Directory.GetCurrentDirectory() /video/ ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds() .mp4; // 校验预览状态未预览无法进行录像 if (irealHanlde 0) { MessageBox.Show(请先预览再进行录像); return; } // 未录像状态开启录像 if (!isOpen) { // 调用开始录像接口参数为预览句柄、存储路径 if (!CHCNetSDK.NET_DVR_SaveRealData(irealHanlde, MP4Path)) { lastError CHCNetSDK.NET_DVR_GetLastError(); MessageBox.Show(录像失败 lastError); return; } else { MessageBox.Show(录像成功); // 切换录像状态标识 isOpen !isOpen; // 更新按钮状态为“停止录像” button8.Text 停止录像; } } else // 已录像状态停止录像 { // 调用停止录像接口 if (!CHCNetSDK.NET_DVR_StopSaveRealData(irealHanlde)) { MessageBox.Show(停止录像失败); return ; } else { // 切换录像状态标识 isOpen !isOpen; // 更新按钮状态为“开始录像” button8.Text 开始录像; } } }核心要点与易错点路径合法性录像存储路径需确保目录存在代码中未创建 video 目录需手动创建或补充目录创建逻辑否则会导致录像失败操作前提录像必须在预览开启后执行未预览时无法调用录像接口状态同步录像状态标识isOpen需与按钮状态保持同步避免状态混乱导致操作异常8. 窗体关闭事件Form1_FormClosing——资源清理/// summary /// 窗体关闭事件释放 SDK 资源避免内存泄漏 /// 核心逻辑调用 SDK 资源清理接口释放所有占用的 SDK 资源 /// /summary private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // 调用海康 SDK 资源清理接口释放所有 SDK 相关资源 CHCNetSDK.NET_DVR_Cleanup(); }核心要点与易错点资源清理必要性必须在窗体关闭时调用 SDK 清理接口否则会导致 SDK 资源泄漏影响后续程序运行清理时机需在窗体关闭前执行资源清理确保所有操作完成后再释放资源避免资源释放过早导致的异常三、整体核心注意事项与优化建议1. 操作核心注意事项SDK 依赖需提前安装海康 SDK确保相关依赖库如 CHCNetSDK.dll已正确引入否则会导致接口调用失败参数一致性所有操作参数通道号、设备 IP、端口等需与设备实际配置一致避免操作失败状态校验所有操作前需校验对应状态登录、预览、录像避免在无效状态下执行操作导致异常资源释放登录、预览、录像等操作完成后需及时释放对应资源窗体关闭时必须清理 SDK 资源路径合法性截图、录像存储目录需提前创建否则会导致文件存储失败可补充目录自动创建逻辑2. 代码优化建议目录自动创建补充 image、video 目录的自动创建逻辑避免手动创建目录的繁琐提升用户体验日志完善补充 SDK 操作日志记录记录操作过程、错误码等信息便于线上问题排查参数配置将通道号、码流类型等参数提取到界面输入框便于用户根据设备实际配置修改无需修改代码异常处理细化异常提示针对不同操作失败场景如登录失败、预览失败给出更具体的错误提示便于用户排查问题代码复用将参数校验、错误码提示、目录创建等通用逻辑封装为方法减少代码冗余提升可维护性资源优化在退出登录、停止预览/录像时补充资源释放的完整性校验确保所有资源均被正常释放3. 测试要点环境准备确保海康摄像头正常运行与程序所在设备在同一局域网网络互通SDK 已正确安装并配置功能测试依次测试 SDK 初始化、登录/退出、预览/停止预览、云台控制、截图、录像等功能验证各操作是否正常执行异常测试测试空参数登录、未登录预览、未预览云台控制等场景验证程序异常处理能力兼容性测试验证不同格式JPEG/BMP截图、录像文件的存储与打开确保媒体文件正常可用

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑