using ivf_tl_Entity.GlobalEnums; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading.Tasks; namespace ivf_tl_Entity.CameraEntitys { /// /// 相机助手类 /// public class Camera { public event Action ExceptionLogEvent; private int index = 0; private int width = 0; private int height = 0; private int exposure = 0; [MarshalAs(UnmanagedType.LPTStr)] public string NumBer = ""; /// /// MVC数字相机的索引号(从0开始),用于指定要进行初始化操作的相机。 /// public int Index { get { return index; } } /// /// 图像宽度 /// public int Width { get { return width; } } /// /// 图像高度 /// public int Height { get { return height; } } /// /// 曝光时间(单位:100us) /// public int Exposure { get { return exposure; } } /// /// CCD是否加载 /// public bool IsInit { get; set; } = false; /// /// CCD是否开启 /// public bool IsStart { get; set; } = false; /// /// 图像字节数组 /// public byte[] SourceBuffer { get { byte[] sourceBuffer = new byte[this.width * this.height * 3]; Marshal.Copy(pDest, sourceBuffer, 0, sourceBuffer.Length); return sourceBuffer; } } /// /// 获取相机对应得序列号 /// /// [HandleProcessCorruptedStateExceptions] [SecurityCritical] public int GetNumbet() { try { int result = -1; lock (locker) { StringBuilder strSerial = new StringBuilder(125); result = MVCAPI.MV_Usb2GetSerial(this.hImager, strSerial); NumBer = strSerial.ToString(); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, "获取序列号", null, LogEnum.RunException); return -2; } } /// /// 获取一张图像 /// //public BitmapImage BitmapImage //{ // get // { // Bitmap bitmap = new Bitmap(this.width, this.height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat); // Marshal.Copy(this.SourceBuffer, 0, bmpData.Scan0, this.SourceBuffer.Length); // bitmap.UnlockBits(bmpData); // bitmap.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); // BitmapImage bitmapImage = new BitmapImage(); // using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) // { // bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); // bitmapImage.BeginInit(); // bitmapImage.StreamSource = ms; // bitmapImage.CacheOption = BitmapCacheOption.OnLoad; // bitmapImage.EndInit(); // bitmapImage.Freeze(); // } // return bitmapImage; // } //} /// /// 结构体 /// private CapInfoStruct capInfoStruct = new CapInfoStruct(); /// /// 由MV_Usb2Init返回的MVC设备句柄 /// public IntPtr hImager; /// /// 回传的图像字节数组 /// private IntPtr pDest; public Camera(int index, int width, int height, int exposure) { this.index = index; this.width = width; this.height = height; this.exposure = exposure; pDest = Marshal.AllocCoTaskMem(this.width * this.height * 3); } public Camera(CameraModel model) { this.index = model.Index; this.width = model.Width; this.height = model.Height; this.exposure = model.Exposure; pDest = Marshal.AllocCoTaskMem(this.width * this.height * 3); } /// /// 初使化相机[注:执行init()之后立即执行SetOpMode()以开启像捕捉 2021.11.11] /// /// public int Init() { try { byte[] mGain = new byte[3]; mGain[0] = Convert.ToByte(25); mGain[1] = Convert.ToByte(14); mGain[2] = Convert.ToByte(25); byte Control = Convert.ToByte(04); capInfoStruct.Buffer = Marshal.AllocCoTaskMem(this.width * this.height * 3); capInfoStruct.Width = this.width; capInfoStruct.Height = this.height; capInfoStruct.HorizontalOffset = 0; capInfoStruct.VerticalOffset = 0; capInfoStruct.Exposure = this.exposure; capInfoStruct.Gain = mGain; capInfoStruct.Control = Control; var result = InitCamera(this); if (result == 0) this.IsInit = true; // M8-P3b:相机初始化边界埋点(module=相机)。全 try 兜底。 try { Aivfo.OperationLog.OperationLogger.Log("相机", "初始化", input: new { index, width, height, exposure }, output: new { result, sn = NumBer }, result: result == 0 ? "成功" : "失败", error: result == 0 ? null : $"InitCamera 返回 {result}"); } catch { } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机初始化", null, LogEnum.RunException); return -2; } } public bool DisPose() { try { Marshal.FreeCoTaskMem(capInfoStruct.Buffer); Marshal.FreeCoTaskMem(pDest); return true; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机释放内存", null, LogEnum.RunException); return false; } } public int Usb2Start(IntPtr mControlPtr, int left, int top, int width, int height) { var nRetValue = MVCAPI.MV_Usb2Start(hImager, "MVC Camera Preview", MVCAPI.WS_CHILD | MVCAPI.WS_VISIBLE, left, top, width, height, mControlPtr, 0, (int)System.Threading.ThreadPriority.Highest, (int)System.Threading.ThreadPriority.Highest); return nRetValue; } public int Usb2Stop() { var nRetValue = MVCAPI.MV_Usb2Stop(hImager); return nRetValue; } public int Usb2StartCapture() { try { var nRetValue = MVCAPI.MV_Usb2StartCapture(hImager, true); return nRetValue; } catch (Exception) { return -1; } } public int Usb2StopCapture() { try { var nRetValue = MVCAPI.MV_Usb2StartCapture(hImager, false); return nRetValue; } catch (Exception) { return -1; } } /// /// 多个方法共同锁 /// private static readonly object locker = new object(); [HandleProcessCorruptedStateExceptions] [SecurityCritical] private int InitCamera(Camera camera) { try { int result = -1; lock (locker) { //MVC2000 result = MVCAPI.MV_Usb2Init("MVC2000", out camera.index, ref camera.capInfoStruct, out camera.hImager); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{camera.index}号相机初始化", null, LogEnum.RunException); return -2; } } /// /// 卸载相机 /// /// public int UnInit() { try { var result = UnInit(this); this.IsInit = result == 0; // M8-P3b:相机卸载边界埋点(module=相机)。全 try 兜底。 try { Aivfo.OperationLog.OperationLogger.Log("相机", "卸载", input: new { index }, output: new { result }, result: result == 0 ? "成功" : "失败"); } catch { } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机卸载", null, LogEnum.RunException); return -1; } } [HandleProcessCorruptedStateExceptions] [SecurityCritical] private int UnInit(Camera camera) { try { int result = -1; lock (locker) { result = MVCAPI.MV_Usb2Uninit(ref hImager); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{camera.index}号相机卸载", null, LogEnum.RunException); return -2; } } /// /// 设置摄像头的采集模式为连续采集模式 /// /// public int SetOpMode() { try { if (this.IsInit == false) return -1; var result = SetOpMode(this); this.IsStart = result == 0; return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机设置采集模式", null, LogEnum.RunException); return -1; } } [HandleProcessCorruptedStateExceptions] [SecurityCritical] private int SetOpMode(Camera camera) { try { int result = -1; lock (locker) { result = MVCAPI.MV_Usb2SetOpMode(camera.hImager, 0, false); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{camera.index}号相机设置采集模式", null, LogEnum.RunException); return -2; } } /// /// 抓取一张图像 /// /// 返回该图字节数组 public int GetRgbData() { try { if (this.IsStart == false) return -1; return GetRgbData(this); } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机抓图", null, LogEnum.RunException); return -2; } } [HandleProcessCorruptedStateExceptions] [SecurityCritical] private int GetRgbData(Camera camera) { try { int result = -1; lock (locker) { result = MVCAPI.MV_Usb2GetRgbData(camera.hImager, ref camera.capInfoStruct, camera.pDest); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{camera.index}号相机抓图", null, LogEnum.RunException); return -2; } } /// /// 抓取一张图像 /// /// 返回该图字节数组 public int GetRawData() { if (this.IsStart == false) return -1; return GetRawData(this); } private int GetRawData(Camera camera) { try { int result = -1; lock (locker) { result = MVCAPI.MV_Usb2GetRawData(camera.hImager, ref camera.capInfoStruct); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机抓图", null, LogEnum.RunException); return -2; } } /// /// 抓取一张图像 /// /// 返回该图字节数组 public int RawToRgb() { if (this.IsStart == false) return -1; return RawToRgb(this); } private int RawToRgb(Camera camera) { try { int result = -1; lock (locker) { result = MVCAPI.MV_Usb2ConvertRawToRgb(camera.hImager, camera.capInfoStruct.Buffer, camera.width, camera.height, camera.pDest); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{index}号相机RawToRgb", null, LogEnum.RunException); return -2; } } /// /// 设置相机参数 /// /// /// public int SetPartOfCapInfo(int Exposure) { return SetPartOfCapInfo(this, Exposure); } [HandleProcessCorruptedStateExceptions] [SecurityCritical] public int SetPartOfCapInfo(Camera camera, int Exposure) { try { int result; capInfoStruct.Exposure = Exposure; //this.width = model.Width; //this.height = model.Height; //capInfoStruct.Gain[0] = Convert.ToByte(model.Red); //capInfoStruct.Gain[1] = Convert.ToByte(model.Green); //capInfoStruct.Gain[2] = Convert.ToByte(model.Blue); //capInfoStruct.HorizontalOffset = model.HorizontalOffset; //capInfoStruct.VerticalOffset = model.VerticalOffset; //capInfoStruct.Exposure = model.Exposure; //capInfoStruct.Width = this.width; //capInfoStruct.Height = this.height; //capInfoStruct.Buffer = Marshal.AllocCoTaskMem(this.width * this.height); //pDest = Marshal.AllocCoTaskMem(this.width * this.height * 3); lock (locker) { result = MVCAPI.MV_Usb2SetPartOfCapInfo(hImager, ref capInfoStruct); } return result; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{camera.index}号相机设置参数", null, LogEnum.RunException); return -2; } } public bool SaveJPG(string fullName) { MemoryStream memoryStream = null; FileStream fs = null; bool success = false; try { memoryStream = new MemoryStream(this.SourceBuffer); fs = new FileStream(fullName, FileMode.OpenOrCreate); memoryStream.WriteTo(fs); success = true; } catch (Exception ex) { success = false; } finally { if (fs != null) { fs.Close(); fs.Dispose(); } if (memoryStream != null) { memoryStream.Close(); memoryStream.Dispose(); } } return success; } public bool SavePic(string fullName,int width,int height) { try { var a = MVCAPI.SavePic(this.SourceBuffer, width, height, fullName); if (a == 1) return true; return false; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"保存图片", null, LogEnum.RunException); return false; } } } }