banboshi_V1/halftoneproject-master/Code/Device/Scanner.cs
2023-10-31 13:19:29 +08:00

443 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using MvCamCtrl.NET;
using Newtonsoft.Json.Linq;
using static ControllerDllCSharp.ClassLibControllerDll;
namespace ProductionControl.Device
{
public class Scanner : IDisposable
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindow(IntPtr hWnd);
public enum ScannerType
{
[Description("板卡相机")]
GENTL = 0,
[Description("网口相机")]
CC = 1,
}
private ScannerType scannerType;
public Action<int, string> log;
/// <summary>
/// 拍照回传 1-num,文件名.bmp)
/// </summary>
public Action<int, string> ScanEvent;
/// <summary>
/// 曝光
/// </summary>
public float ExposureTime { get; private set; }
/// <summary>
/// 增益
/// </summary>
public float Gain { get; private set; }
/// <summary>
/// 帧率
/// </summary>
public float ResultingFrameRate { get; private set; }
/// <summary>
/// 是否连续模式
/// </summary>
public bool isContinuousMode { get; private set; }
/// <summary>
/// 是否打开设备成功
/// </summary>
public bool IsInit { get; private set; } = false;
//public string ErrInfo { get; private set; }
//private System.Timers.Timer timer = new System.Timers.Timer();
#region
private MyCamera.MV_GENTL_DEV_INFO_LIST m_stGentDeviceList = new MyCamera.MV_GENTL_DEV_INFO_LIST();
private MyCamera.MV_GENTL_IF_INFO_LIST m_stIFInfoList = new MyCamera.MV_GENTL_IF_INFO_LIST();
private MyCamera.MV_CC_DEVICE_INFO_LIST m_stCCDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
private MyCamera m_MyCamera = new MyCamera();
private bool m_bGrabbing = false;//开始采集TAG
private Thread m_hReceiveThread = null;
//显示图像控件句柄
private IntPtr previewHwnd = IntPtr.Zero;
//拍照数量
private int scanNum = 0;
#endregion
public Scanner(ScannerType type)
{
this.scannerType = type;
}
public bool open()
{
if (IsInit) return true;
System.GC.Collect();
int nRet;
if (this.scannerType==ScannerType.GENTL)
{
nRet = MyCamera.MV_CC_EnumInterfacesByGenTL_NET(ref m_stIFInfoList, Config.Scanner_GENTL_CTI);
if (0 != nRet || m_stIFInfoList.nInterfaceNum<1)
{
log?.Invoke(2, $"Enumerate interfaces fail! ({nRet})");
return false;
}
//
MyCamera.MV_GENTL_IF_INFO stIFInfo = (MyCamera.MV_GENTL_IF_INFO)Marshal.PtrToStructure(m_stIFInfoList.pIFInfo[0], typeof(MyCamera.MV_GENTL_IF_INFO));
nRet = MyCamera.MV_CC_EnumDevicesByGenTL_NET(ref stIFInfo, ref m_stGentDeviceList);
if (0 != nRet || m_stGentDeviceList.nDeviceNum<1)
{
log?.Invoke(2, $"Enumerate devices fail! ({nRet})");
return false;
}
// ch:获取选择的设备信息 | en:Get selected device information
MyCamera.MV_GENTL_DEV_INFO device = (MyCamera.MV_GENTL_DEV_INFO)Marshal.PtrToStructure(m_stGentDeviceList.pDeviceInfo[0], typeof(MyCamera.MV_GENTL_DEV_INFO));
// ch:打开设备 | en:Open device
if (null == m_MyCamera)
{
m_MyCamera = new MyCamera();
if (null == m_MyCamera)
{
log?.Invoke(2, $"Open device fail!");
return false;
}
}
nRet = m_MyCamera.MV_CC_CreateDeviceByGenTL_NET(ref device);
if (MyCamera.MV_OK != nRet)
{
log?.Invoke(2, $"Open device fail! ({nRet})");
return false;
}
nRet = m_MyCamera.MV_CC_OpenDevice_NET();
if (MyCamera.MV_OK != nRet)
{
m_MyCamera.MV_CC_DestroyDevice_NET();
log?.Invoke(2, $"Device open fail! ({nRet})");
return false;
}
}
else //CC
{
nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_stCCDeviceList);
if (0 != nRet || m_stCCDeviceList.nDeviceNum<1)
{
log?.Invoke(2, $"Enumerate devices fail! ({nRet})");
return false;
}
// ch:获取选择的设备信息
MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_stCCDeviceList.pDeviceInfo[0], typeof(MyCamera.MV_CC_DEVICE_INFO));
// ch:打开设备 | en:Open device
if (null == m_MyCamera)
{
m_MyCamera = new MyCamera();
if (null == m_MyCamera)
{
log?.Invoke(2, $"Open device fail!");
return false;
}
}
nRet = m_MyCamera.MV_CC_CreateDevice_NET(ref device);
if (MyCamera.MV_OK != nRet)
{
log?.Invoke(2, $"Open device fail! ({nRet})");
return false;
}
nRet = m_MyCamera.MV_CC_OpenDevice_NET();
if (MyCamera.MV_OK != nRet)
{
m_MyCamera.MV_CC_DestroyDevice_NET();
log?.Invoke(2, $"Open device fail! ({nRet})");
return false;
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
{
int nPacketSize = m_MyCamera.MV_CC_GetOptimalPacketSize_NET();
if (nPacketSize > 0)
{
nRet = m_MyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
//if (nRet != MyCamera.MV_OK)
//{
// ShowErrorMsg("Set Packet Size failed!", nRet);
//}
}
else
{
//ShowErrorMsg("Get Packet Size failed!", nPacketSize);
}
}
}
// ch:设置采集[软触发/连续]模式 | en:Set Continues Aquisition Mode
m_MyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
setMode(false); //软触发
//
getParam();
IsInit = true;
//timer.Elapsed += Timer_Elapsed;
//timer.Interval = 100;
//timer.Enabled = true;
return true;
}
public void close()
{
if (!IsInit) return;
IsInit = false;
// ch:取流标志位清零 | en:Reset flow flag bit
if (m_bGrabbing == true)
{
m_bGrabbing = false;
m_hReceiveThread.Join();
}
// ch:关闭设备 | en:Close Device
m_MyCamera.MV_CC_CloseDevice_NET();
m_MyCamera.MV_CC_DestroyDevice_NET();
}
/// <summary>
///
/// </summary>
/// <param name="hwnd">显示图像控件句柄</param>
/// <returns></returns>
public bool start(IntPtr preview_Hwnd)
{
if (!IsInit) return false;
if (m_bGrabbing) return true;
this.previewHwnd= preview_Hwnd;
// ch:标志位置位true | en:Set position bit true
m_bGrabbing = true;
m_hReceiveThread = new Thread(ReceiveThreadProcess);
m_hReceiveThread.Start();
// ch:开始采集 | en:Start Grabbing
int nRet = m_MyCamera.MV_CC_StartGrabbing_NET();
if (MyCamera.MV_OK != nRet)
{
m_bGrabbing = false;
m_hReceiveThread.Join();
log?.Invoke(2, $"Start Grabbing Fail! ({nRet})");
return false;
}
return true;
}
public bool stop()
{
if (!IsInit) return false;
if (!m_bGrabbing) return true;
// ch:标志位设为false | en:Set flag bit false
m_bGrabbing = false;
m_hReceiveThread.Join();
// ch:停止采集 | en:Stop Grabbing
int nRet = m_MyCamera.MV_CC_StopGrabbing_NET();
if (nRet != MyCamera.MV_OK)
{
log?.Invoke(2, $"Stop Grabbing Fail! ({nRet})");
return false;
}
return true;
}
#region private
/// <summary>
/// false-软触发 true-连续
/// </summary>
/// <param name="type"></param>
public void setMode(bool isContinuous)
{
if (isContinuous)
{
m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
}
else
{
m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
// ch:触发源选择:0 - Line0;
// 1 - Line1;
// 2 - Line2;
// 3 - Line3;
// 4 - Counter;
// 7 - Software;
//if (cbSoftTrigger.Checked)
m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
//else
// m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
}
isContinuousMode = isContinuous;
}
public void setPreviewWin(IntPtr preview_Hwnd)
{
this.previewHwnd = preview_Hwnd;
}
public void ReceiveThreadProcess()
{
MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT();
MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();
int nRet = MyCamera.MV_OK;
while (m_bGrabbing)
{
nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000);
if (nRet == MyCamera.MV_OK)
{
if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType)
|| stFrameInfo.stFrameInfo.nFrameLen == 0)
{
m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
continue;
}
//pictureBox1显示
if (this.previewHwnd != IntPtr.Zero && IsWindow(this.previewHwnd))
{
stDisplayInfo.hWnd = this.previewHwnd;// pictureBox1.Handle;
stDisplayInfo.pData = stFrameInfo.pBufAddr;
stDisplayInfo.nDataLen = stFrameInfo.stFrameInfo.nFrameLen;
stDisplayInfo.nWidth = stFrameInfo.stFrameInfo.nWidth;
stDisplayInfo.nHeight = stFrameInfo.stFrameInfo.nHeight;
stDisplayInfo.enPixelType = stFrameInfo.stFrameInfo.enPixelType;
m_MyCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);
}
//保存
if (this.scanNum>0)//save tag
{
MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM();
//lock (BufForDriverLock)
{
stSaveFileParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
stSaveFileParam.enPixelType = stFrameInfo.stFrameInfo.enPixelType;
stSaveFileParam.pData = stFrameInfo.pBufAddr;//m_BufForDriver;
stSaveFileParam.nDataLen = stFrameInfo.stFrameInfo.nFrameLen;
stSaveFileParam.nHeight = stFrameInfo.stFrameInfo.nHeight;
stSaveFileParam.nWidth = stFrameInfo.stFrameInfo.nWidth;
stSaveFileParam.iMethodValue = 2;
//Save path
stSaveFileParam.pImagePath = "Image_w" + stSaveFileParam.nWidth.ToString() + "_h" + stSaveFileParam.nHeight.ToString() + "_fn" + stFrameInfo.stFrameInfo.nFrameNum.ToString() + ".bmp";
nRet = m_MyCamera.MV_CC_SaveImageToFile_NET(ref stSaveFileParam);
if (MyCamera.MV_OK == nRet)
{
ScanEvent?.Invoke(this.scanNum--, stSaveFileParam.pImagePath);
}
}
}
//free
m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
}
else
{
Thread.Sleep(5);
}
}
}
// ch:去除自定义的像素格式 | en:Remove custom pixel formats
private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat)
{
Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000));
if (0x80000000 == nResult)
{
return true;
}
else
{
return false;
}
}
#endregion
public void getParam()
{
if (!IsInit) return;
MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
int nRet = m_MyCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
if (MyCamera.MV_OK == nRet)
{
ExposureTime = stParam.fCurValue;//.ToString("F1");
}
nRet = m_MyCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
if (MyCamera.MV_OK == nRet)
{
Gain = stParam.fCurValue;//.ToString("F1");
}
nRet = m_MyCamera.MV_CC_GetFloatValue_NET("ResultingFrameRate", ref stParam);
if (MyCamera.MV_OK == nRet)
{
ResultingFrameRate = stParam.fCurValue;//.ToString("F1");
}
}
public void setParam(float exposureTime, float gain, float resultingFrameRate)
{
if (!IsInit) return;
m_MyCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
int nRet = m_MyCamera.MV_CC_SetFloatValue_NET("ExposureTime", exposureTime);
if (nRet != MyCamera.MV_OK)
{
log?.Invoke(0, $"Set Exposure Time Fail! ({nRet})");
}
m_MyCamera.MV_CC_SetEnumValue_NET("GainAuto", 0);
nRet = m_MyCamera.MV_CC_SetFloatValue_NET("Gain", gain);
if (nRet != MyCamera.MV_OK)
{
log?.Invoke(0, $"Set Gain Time Fail! ({nRet})");
}
nRet = m_MyCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", resultingFrameRate);
if (nRet != MyCamera.MV_OK)
{
log?.Invoke(0, $"Set AcquisitionFrameRate Time Fail! ({nRet})");
}
}
public bool scan(int num)
{
if (!IsInit) return false;
if (!isContinuousMode)
{
// ch:触发命令 | en:Trigger command
int nRet = m_MyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
if (MyCamera.MV_OK != nRet)
{
log?.Invoke(0, $"Trigger Software Fail! ({nRet})");
return false;
}
}
this.scanNum= num;
return true;
}
public void Dispose()
{
stop();
}
}
}