using System; namespace IvfTl.Hardware { /// /// 单台相机(MVC2000)的唯一持有者。封装 MVCAPI P/Invoke。 /// 蓝本:autofocustool Camera(含 _pDest 空保护 + 锁内释放)。 /// ⚠ 所有原生调用必须走【全进程统一相机锁】(ICameraGate),替代现状三套各自的 static locker。 /// ⚠ 所有进 native 的实现方法必须加 [HandleProcessCorruptedStateExceptions][SecurityCritical] 防 native 崩溃拖垮进程。 /// 接口签名权威:13 文档 §3.3。 /// public interface ICamera : IDisposable { int Index { get; } int Width { get; } int Height { get; } int Exposure { get; } // 单位 100us string SerialNumber { get; } bool IsInit { get; } bool IsStart { get; } // ── 生命周期 ── /// 初始化(MV_Usb2Init MVC2000)。返回 0 成功。需立即 SetOpMode 才能抓图。 int Init(byte redGain = 25, byte greenGain = 14, byte blueGain = 25); /// 采集模式:0=单帧拍照(对焦/调试抓图用),1=实时预览。返回 0 成功。 int SetOpMode(byte mode = 0, bool strobe = false); /// 读相机序列号到 SerialNumber。返回 0 成功。 int ReadSerial(); /// 卸载相机(MV_Usb2Uninit)。返回 0 成功。 int UnInit(); // ── 参数 ── /// 设曝光(单位 100us)。返回 0 成功。 int SetExposure(int exposure100us); /// 设 RGB 三通道增益(0-255)。返回 0 成功。 int SetGain(byte red, byte green, byte blue); // ── 抓帧(单帧)── /// 抓一帧 RGB 到内部缓冲。返回 0 成功;之后用 GetFrameBuffer 取像素。 int GrabRgb(); /// 取当前帧像素(24bpp BGR, W*H*3)。_pDest 已释放返回 null(调用方按抓帧失败重试)。 byte[] GetFrameBuffer(); /// 抓一帧并返回像素的便捷重载,内置"丢残留帧 + 到位延时 + 重试"语义(13 §3.5)。 /// discardStale=true 时先 GrabRgb 丢弃一帧再抓有效帧(运动后旧帧滞留修复,对应 af 双 Grab)。 /// preDelayMs:抓前等待(电机到位稳定),retry:抓帧失败重试次数。失败返回 null。 byte[] GrabStable(int preDelayMs = 0, bool discardStale = true, int retry = 2); // ── 实时预览(贴 WPF 窗口,operate 调试/control 预览用;af 不需要)── /// 把实时画面贴到宿主控件句柄。对应 control/operate Usb2Start。返回 0 成功。 int StartPreview(IntPtr hostControl, int left, int top, int width, int height); int StopPreview(); // ── operate 调试页"无图模式"两步抓帧 + 存图(M1-B2:调试页接入 lease.Camera 后转发到底层 Camera)── /// 抓取一帧 RAW 到内部缓冲(对应底层 Camera.GetRawData)。返回 0 成功;之后配 RawToRgb 转 RGB。 int GrabRaw(); /// 把内部 RAW 缓冲转 RGB(对应底层 Camera.RawToRgb)。返回 0 成功。 int RawToRgb(); /// 把当前帧像素保存为图片文件(对应 operate 调试页 Camera.SavePic)。成功返回 true。 bool SavePic(string fullName, int width, int height); /// 桥接对象:返回内部包装的具体 Camera(迁移期过渡,新代码只用本接口方法)。 object RawCamera { get; } } }