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;
}
}
}
}