You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

453 lines
15 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using MvCamCtrl.NET;
using MvCamCtrl.NET.CameraParams;
using SlnMesnac.Config;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace SlnMesnac.Common
{
public class CCameraHik
{
#region 单例实现
private static readonly Lazy<CCameraHik> lazy = new Lazy<CCameraHik>(() => new CCameraHik());
public static CCameraHik Instance
{
get
{
return lazy.Value;
}
}
#endregion
public delegate void RefreshCamera(string ip,bool flag);
public static event RefreshCamera RefreshCameraEvent;
private DebugConfig config = DebugConfig.Instance;
/// <summary>
/// 已经打开的设备集合
/// </summary>
public static Dictionary<string, CCamera> m_MyCameras = new Dictionary<string, CCamera>();
/// <summary>
/// 枚举到的设备集合
/// </summary>
List<CCameraInfo> m_ltDeviceList = new List<CCameraInfo>();
Thread m_hReceiveThread1 = null;
Thread m_hReceiveThread2 = null;
bool m_bGrabbing = false;
// 存放照片路径
public string PicturePath = System.Environment.CurrentDirectory + "/picture/";
// ch:用于从驱动获取图像的缓存 | en:Buffer for getting image from driver
private static Object BufForDriverLock = new Object();
CImage m_pcImgForDriver = null; // 图像信息
CFrameSpecInfo m_pcImgSpecInfo = null; // 图像的水印信息
UInt32 m_nCurWidth = 0;
UInt32 m_nCurHeight = 0;
MvGvspPixelType m_emPixelType = MvGvspPixelType.PixelType_Gvsp_Mono8;
/// <summary>
/// 枚举设备
/// </summary>
public void DeviceListAndStart()
{
// ch:创建设备列表 | en:Create Device List
System.GC.Collect();
//枚举设备
int nRet = CSystem.EnumDevices(CSystem.MV_GIGE_DEVICE | CSystem.MV_USB_DEVICE, ref m_ltDeviceList);
if (0 != nRet)
{
// ShowErrorMsg("Enumerate devices fail!", 0);
return;
}
//打开设备
foreach (CCameraInfo deviceInfo in m_ltDeviceList)
{
bool flag = OpenDevice(deviceInfo);
if(!flag)
{
// TODO 重连
}
}
Console.WriteLine("设备数:"+m_ltDeviceList.Count);
StartGrab();
}
public bool OpenDevice(CCameraInfo device)
{
try
{
CCamera item = new CCamera();
int nRet = item.CreateHandle(ref device);
if (CErrorDefine.MV_OK != nRet)
{
return false;
}
nRet = item.OpenDevice();
if (CErrorDefine.MV_OK != nRet)
{
item.DestroyHandle();
Console.WriteLine("Device open fail!", nRet);
return false;
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
if (device.nTLayerType == CSystem.MV_GIGE_DEVICE)
{
int nPacketSize = item.GIGE_GetOptimalPacketSize();
if (nPacketSize > 0)
{
nRet = item.SetIntValue("GevSCPSPacketSize", (uint)nPacketSize);
if (nRet != CErrorDefine.MV_OK)
{
Console.WriteLine("Set Packet Size failed!", nRet);
}
}
}
// 设置触发模式
item.SetEnumValue("TriggerMode", (uint)MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
// ch:触发源设为软触发 | en:Set trigger source as Software
item.SetEnumValue("TriggerSource", (uint)MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
// ch:取图前的必要操作步骤 | en:Necessary operation before grab
CGigECameraInfo cGigEDeviceInfo = (CGigECameraInfo)device;
uint nIp1 = ((cGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24);
uint nIp2 = ((cGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16);
uint nIp3 = ((cGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8);
uint nIp4 = (cGigEDeviceInfo.nCurrentIp & 0x000000ff);
string ip = $"{nIp1}.{nIp2}.{nIp3}.{nIp4}";
Console.WriteLine("DevIP:" + ip);
RefreshCameraEvent?.Invoke(ip, true);
m_MyCameras.Add(ip, item);
Console.WriteLine("open success");
return true;
}
catch (Exception ex)
{
Console.WriteLine("open()"+ex.Message);
return false;
}
}
// ch:取图前的必要操作步骤 | en:Necessary operation before grab
private Int32 NecessaryOperBeforeGrab(CCamera m_MyCamera)
{
// ch:取图像宽 | en:Get Iamge Width
CIntValue pcWidth = new CIntValue();
int nRet = m_MyCamera.GetIntValue("Width", ref pcWidth);
if (CErrorDefine.MV_OK != nRet)
{
//ShowErrorMsg("Get Width Info Fail!", nRet);
return nRet;
}
m_nCurWidth = (UInt32)pcWidth.CurValue;
// ch:取图像高 | en:Get Iamge Height
CIntValue pcHeight = new CIntValue();
nRet = m_MyCamera.GetIntValue("Height", ref pcHeight);
if (CErrorDefine.MV_OK != nRet)
{
// ShowErrorMsg("Get Height Info Fail!", nRet);
return nRet;
}
m_nCurHeight = (UInt32)pcHeight.CurValue;
// ch:取像素格式 | en:Get Pixel Format
CEnumValue pcPixelFormat = new CEnumValue();
nRet = m_MyCamera.GetEnumValue("PixelFormat", ref pcPixelFormat);
if (CErrorDefine.MV_OK != nRet)
{
// ShowErrorMsg("Get Pixel Format Fail!", nRet);
return nRet;
}
m_emPixelType = (MvGvspPixelType)pcPixelFormat.CurValue;
return CErrorDefine.MV_OK;
}
public void StartGrab()
{
m_bGrabbing = true;
foreach (KeyValuePair<string,CCamera> pair in m_MyCameras)
{
int nRet = NecessaryOperBeforeGrab(pair.Value);
if (CErrorDefine.MV_OK != nRet)
{
// TODO重新销毁打开
return;
}
if (config.Scanner1IP == pair.Key)
{
m_hReceiveThread1 = new Thread(() => ReceiveThreadProcess(pair.Key,pair.Value));
m_hReceiveThread1.Start();
// ch:开始采集 | en:Start Grabbing
nRet = pair.Value.StartGrabbing();
if (CErrorDefine.MV_OK != nRet)
{
m_bGrabbing = false;
m_hReceiveThread1.Join();
// ShowErrorMsg("Start Grabbing Fail!", nRet);
return;
}
}
pair.Value.SetEnumValue("ExposureAuto", 0);
nRet = pair.Value.SetFloatValue("ExposureTime", 45000.0f);
if (nRet != CErrorDefine.MV_OK)
{
// ShowErrorMsg("Set Exposure Time Fail!", nRet);
}
pair.Value.SetEnumValue("GainAuto", 0);
nRet = pair.Value.SetFloatValue("Gain", 10.0f);
if (nRet != CErrorDefine.MV_OK)
{
// ShowErrorMsg("Set Gain Fail!", nRet);
}
nRet = pair.Value.SetFloatValue("AcquisitionFrameRate", 9.4f);
if (nRet != CErrorDefine.MV_OK)
{
// ShowErrorMsg("Set Frame Rate Fail!", nRet);
}
}
}
public void StopGrab()
{
try
{
m_bGrabbing = false;
if (m_hReceiveThread1 != null && m_hReceiveThread1.IsAlive)
{
m_hReceiveThread1.Join(); // 等待线程结束
}
if (m_hReceiveThread2 != null && m_hReceiveThread2.IsAlive)
{
m_hReceiveThread2.Join(); // 等待线程结束
}
foreach (KeyValuePair<string, CCamera> pair in m_MyCameras)
{
// ch:停止采集 | en:Stop Grabbing
int nRet = pair.Value.StopGrabbing();
if (nRet != CErrorDefine.MV_OK)
{
Console.WriteLine($"相机{pair.Key} Stop Grabbing Fail!", nRet);
}
// 销毁句柄
nRet = pair.Value.CloseDevice();
if (nRet != CErrorDefine.MV_OK)
{
Console.WriteLine($"相机{pair.Key} 关闭设备 Fail!", nRet);
}
// 销毁句柄
nRet = pair.Value.DestroyHandle();
if (nRet != CErrorDefine.MV_OK)
{
Console.WriteLine($"相机{pair.Key} 销毁句柄 Fail!", nRet);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"stopGarb异常:" + ex.Message);
}
}
/// <summary>
/// 箱体码扫码成功以后触发OCR相机拍照解析
/// </summary>
/// <returns></returns>
public bool TriggerGather()
{
//采集前确保照片文件夹为空,防止照片比对出错
DeleteAllPictures(PicturePath);
// 两个相机采集照片
foreach (KeyValuePair<string,CCamera> pair in m_MyCameras)
{
// 采集一次
// ch:触发命令 | en:Trigger command
int nRet = pair.Value.SetCommandValue("TriggerSoftware");
if (CErrorDefine.MV_OK != nRet)
{
return false;
}
}
return true;
}
/// <summary>
/// 照片接收线程
/// </summary>
/// <param name="ip"></param>
/// <param name="m_MyCamera"></param>
public void ReceiveThreadProcess(string ip ,CCamera m_MyCamera)
{
int nRet = CErrorDefine.MV_OK;
while (m_bGrabbing)
{
if (ip == config.Scanner1IP)
{
Console.WriteLine($"{DateTime.Now} 线程1等待接收数据 -->");
}
CFrameout pcFrameInfo = new CFrameout();
CDisplayFrameInfo pcDisplayInfo = new CDisplayFrameInfo();
CPixelConvertParam pcConvertParam = new CPixelConvertParam();
nRet = m_MyCamera.GetImageBuffer(ref pcFrameInfo, 1000);
if (CErrorDefine.MV_OK == nRet)
{
lock (BufForDriverLock)
{
if (null != m_pcImgForDriver)
{
m_pcImgForDriver.Destory();
m_pcImgForDriver = null;
}
m_pcImgForDriver = pcFrameInfo.Image.Clone() as CImage;
m_pcImgSpecInfo = pcFrameInfo.FrameSpec;
}
pcDisplayInfo.Image = pcFrameInfo.Image;
SaveAndChangeJpg(ip,m_MyCamera);
m_MyCamera.FreeImageBuffer(ref pcFrameInfo);
}
}
}
/// <summary>
/// 保存照片OCR解析删除照片
/// </summary>
/// <param name="ip"></param>
/// <param name="m_MyCamera"></param>
private void SaveAndChangeJpg(string ip,CCamera m_MyCamera)
{
string testPath = PicturePath + "3.jpg";
CSaveImgToFileParam stSaveFileParam = new CSaveImgToFileParam();
lock (BufForDriverLock)
{
if (null == m_pcImgForDriver || 0 == m_pcImgForDriver.FrameLen)
{
return;
}
stSaveFileParam.ImageType = MV_SAVE_IAMGE_TYPE.MV_IMAGE_JPEG;
stSaveFileParam.Image = m_pcImgForDriver;
stSaveFileParam.Quality = 80;
stSaveFileParam.MethodValue = 2;
stSaveFileParam.ImagePath = PicturePath + $"photo_{ip}.jpg";
int nRet = m_MyCamera.SaveImageToFile(ref stSaveFileParam);
if (CErrorDefine.MV_OK != nRet)
{
Console.WriteLine("保存照片失败");
return;
}
}
}
// 删除指定文件里的照片
private void DeletePhoto(string filePath)
{
try
{
// Check if the file exists
if (File.Exists(filePath))
{
// Delete the file
File.Delete(filePath);
Console.WriteLine("Photo deleted successfully.");
}
else
{
Console.WriteLine("File does not exist.");
}
}
catch (Exception ex)
{
Console.WriteLine("Error deleting photo: " + ex.Message);
}
}
/// <summary>
/// 删除文件夹所有照片
/// </summary>
/// <param name="path"></param>
static void DeleteAllPictures(string path)
{
try
{
// 检查照片路径是否存在
if (Directory.Exists(path))
{
// 获取文件夹中的所有文件
string[] files = Directory.GetFiles(path);
// 遍历文件并删除
foreach (string file in files)
{
File.Delete(file);
Console.WriteLine($"Deleted file: {file}");
}
Console.WriteLine("All pictures deleted successfully.");
}
else
{
Console.WriteLine("无路径");
}
}
catch (Exception ex)
{
Console.WriteLine($"DeleteAllPictures异常: {ex.Message}");
}
}
}
}