geboshi_V1/LeatherProject/LeatherApp/Device/CamerCardDev.cs
2024-03-07 14:03:22 +08:00

825 lines
35 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.Drawing;
using System.Drawing.Imaging;
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 LeatherApp.Interface;
//using MvCamCtrl.NET;
using MvFGCtrlC.NET;
using Newtonsoft.Json.Linq;
using OpenCvSharp;
using OpenCvSharp.Dnn;
//using static ControllerDllCSharp.ClassLibControllerDll;
namespace LeatherApp.Device
{
public class CamerCardDev : ABSCamerCardDev,IDisposable
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindow(IntPtr hWnd);
[DllImport("kernel32.dll", EntryPoint = "RtlCopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
//
private int scanIndex = 0; //实际拍照从1开始命名因先加的1
private string bmpSavePath;
/// <summary>
/// 曝光 3.00-10000.00
/// </summary>
public float ExposureTime { get; private set; }
/// <summary>
/// 增益 0-23.981199
/// </summary>
public float Gain { get; private set; }
/// <summary>
/// 帧率 0-429496.718750
/// </summary>
public float ResultingFrameRate { get; private set; }
/// <summary>
/// 图片大小
/// </summary>
public System.Drawing.Size size { 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();
private int _scannerCardIndex = 0;//采集卡索引
private int _scannerIndex=0;//相机索引(一个采集卡上可插多个相机)
#region
public enum SAVE_IAMGE_TYPE
{
Image_Undefined = 0, // ch:未定义的图像格式 | en:Undefined Image Type
Image_Bmp = 1, // ch:BMP图像格式 | en:BMP Image Type
Image_Jpeg = 2, // ch:JPEG图像格式 | en:Jpeg Image Type
}
// ch:判断用户自定义像素格式 | en:Determine custom pixel format
public const Int32 CUSTOMER_PIXEL_FORMAT = unchecked((Int32)0x80000000);
public const UInt32 TRIGGER_MODE_ON = 1; // ch:触发模式开 | en:Trigger mode on
public const UInt32 TRIGGER_MODE_OFF = 0; // ch:触发模式关 | en:Trigger mode off
CSystem m_cSystem = new CSystem(); // ch:操作采集卡 | en:Interface operations
CInterface m_cInterface = null; // ch:操作采集卡和设备 | en:Interface and device operation
CDevice m_cDevice = null; // ch:操作设备和流 | en:Device and stream operation
CStream m_cStream = null; // ch:操作流和缓存 | en:Stream and buffer operation
uint m_nInterfaceNum = 0; // ch:采集卡数量 | en:Interface number
bool m_bIsIFOpen = false; // ch:采集卡是否打开 | en:Whether to open interface
bool m_bIsDeviceOpen = false; // ch:设备是否打开 | en:Whether to open device
bool m_bIsGrabbing = false; // ch:是否在抓图 | en:Whether to start grabbing
uint m_nTriggerMode = TRIGGER_MODE_OFF; // ch:触发模式 | en:Trigger Mode
bool m_bThreadState = false; // ch:线程状态 | en:Thread state
Thread m_hGrabThread = null; // ch:取流线程 | en:Grabbing thread
private static Object m_LockForSaveImage = new Object(); // ch:存图锁 | en:Lock for saving image
IntPtr m_pDataBuf = IntPtr.Zero; // ch:数据缓存 | en:Data buffer
uint m_nDataBufSize = 0; // ch:数据缓存大小 | en:Length of data buffer
IntPtr m_pSaveImageBuf = IntPtr.Zero; // ch:图像缓存 | en:Image buffer
uint m_nSaveImageBufSize = 0; // ch:图像缓存大小 | en:Length of image buffer
MV_FG_INPUT_IMAGE_INFO m_stImageInfo = new MV_FG_INPUT_IMAGE_INFO(); // ch:图像信息 | en:Image info
delegate void ShowDisplayError(int nRet);
//显示图像控件句柄
private PictureBox previewHwnd=null;
#endregion
public CamerCardDev( )
{
}
public override bool open(int cardIndex = 0,int scannerIndex = 0)
{
if (IsInit) return true;
//m_stIFInfoList = _m_stIFInfoList;
_scannerCardIndex = cardIndex;
_scannerIndex = scannerIndex;
System.GC.Collect();
try
{
int nRet = 0;
bool bChanged = false;
// ch:枚举采集卡 | en:Enum interface
nRet = m_cSystem.UpdateInterfaceList(
CParamDefine.MV_FG_CAMERALINK_INTERFACE | CParamDefine.MV_FG_GEV_INTERFACE | CParamDefine.MV_FG_CXP_INTERFACE | CParamDefine.MV_FG_XoF_INTERFACE,
ref bChanged);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Enum Interface failed, ErrorCode:" + nRet.ToString("X"));
return false;
}
m_nInterfaceNum = 0;
// ch:获取采集卡数量 | en:Get interface num
nRet = m_cSystem.GetNumInterfaces(ref m_nInterfaceNum);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Get interface number failed, ErrorCode:" + nRet.ToString("X"));
return false;
}
if (0 == m_nInterfaceNum)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "No interface found");
return false;
}
if (cardIndex + 1 > m_nInterfaceNum)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "cardIndex > interface.count!");
return false;
}
//打开采集卡
// 如果已经打开,则先关闭采集卡
if (null != m_cInterface)
{
m_cInterface.CloseInterface();
m_cInterface = null;
}
// ch:打开采集卡,获得采集卡句柄 | en:Open interface, get handle
nRet = m_cSystem.OpenInterface((uint)cardIndex, out m_cInterface);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Open Interface failed, ErrorCode:" + nRet.ToString("X"));
return false;
}
m_bIsIFOpen = true;
//====枚举设备
uint nDeviceNum = 0;
// ch:枚举采集卡上的相机 | en:Enum camera of interface
nRet = m_cInterface.UpdateDeviceList(ref bChanged);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Update device list failed, ErrorCode:" + nRet.ToString("X"));
return false;
}
// ch:获取设备数量 | en:Get device number
nRet = m_cInterface.GetNumDevices(ref nDeviceNum);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Get devices number failed, ErrorCode:" + nRet.ToString("X"));
return false;
}
if (0 == nDeviceNum)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "No Device found");
return false;
}
if (scannerIndex + 1 > nDeviceNum)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "scannerIndex > Device.count!");
return false;
}
//====打开设备
// 如果已经打开,则先关闭通道
if (null != m_cStream)
{
m_cStream.CloseStream();
m_cStream = null;
}
// 如果已经打开,则先关闭设备
if (null != m_cDevice)
{
m_cDevice.CloseDevice();
m_cDevice = null;
}
// ch:打开设备,获得设备句柄 | en:Open device, get handle
nRet = m_cInterface.OpenDevice((uint)scannerIndex, out m_cDevice);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Open device failed, ErrorCode:" + nRet.ToString("X"));
return false;
}
m_bIsDeviceOpen = true;
//=====打开触发模式
CParam cDeviceParam = new CParam(m_cInterface);
// ch:打开触发模式 | en:Open Trigger Mode
//nRet = cDeviceParam.SetEnumValue("TriggerMode", TRIGGER_MODE_ON);
//if (CErrorCode.MV_FG_SUCCESS != nRet)
//{
// WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Turn on trigger mode failed, ErrorCode:" + nRet.ToString("X"));
// //关闭设备和采集卡
// m_cDevice.CloseDevice();
// m_bIsDeviceOpen = false;
// m_cInterface.CloseInterface();
// m_cInterface = null;
// return false;
//}
m_nTriggerMode = TRIGGER_MODE_ON;
cDeviceParam.SetEnumValue("TriggerSource", (uint)0);//CC1=0
// ch:注册回调函数 | en:Register image callback //本类不使用回调,使用线程主动循环读取
//ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
//nRet = device.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
//if (MyCamera.MV_OK != nRet)
//{
// WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, $"Register image callback failed! ({nRet})");
// return false;
//}
//开始采集
//startGrab();
//
getParam();
IsInit = true;
//timer.Elapsed += Timer_Elapsed;
//timer.Interval = 100;
//timer.Enabled = true;
return true;
}
catch (Exception ex)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, ex.Message);
return false;
}
}
public override void close()
{
if (!IsInit) return;
try
{
IsInit = false;
//=====关闭设备
if (m_bThreadState)
{
m_bThreadState = false;
m_hGrabThread.Join();
}
int nRet = 0;
if (m_bIsGrabbing)
{
// ch:停止取流 | en:Stop Acquisition
nRet = m_cStream.StopAcquisition();
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low,"Stop acquistion failed, ErrorCode:" + nRet.ToString("X"));
}
m_bIsGrabbing = false;
}
if (null != m_cStream)
{
// ch:关闭流通道 | en:Close stream channel
nRet = m_cStream.CloseStream();
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low,"Close stream channel failed, ErrorCode:" + nRet.ToString("X"));
}
m_cStream = null;
}
if (null != m_cDevice)
{
// ch:关闭设备 | en:Close device
nRet = m_cDevice.CloseDevice();
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low,"Close device failed, ErrorCode:" + nRet.ToString("X"));
}
m_cDevice = null;
}
m_bIsDeviceOpen = false;
if (IntPtr.Zero != m_pDataBuf)
{
Marshal.FreeHGlobal(m_pDataBuf);
m_pDataBuf = IntPtr.Zero;
}
m_nDataBufSize = 0;
if (IntPtr.Zero != m_pSaveImageBuf)
{
Marshal.FreeHGlobal(m_pSaveImageBuf);
m_pSaveImageBuf = IntPtr.Zero;
}
m_nSaveImageBufSize = 0;
//======关闭采集卡
if (null == m_cInterface)
return;
// ch:关闭采集卡 | en:Close interface
nRet = m_cInterface.CloseInterface();
//if (CErrorCode.MV_FG_SUCCESS != nRet)
//{
// WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low,"Close interface failed, ErrorCode:" + nRet.ToString("X"));
// return;
//}
m_cInterface = null;
m_bIsIFOpen = false;
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="hwnd">显示图像控件句柄</param>
/// <returns></returns>
public override bool start(PictureBox preview_Hwnd,string bmp_save_path)
{
if (!IsInit) return false;
this.previewHwnd= preview_Hwnd;
this.bmpSavePath = bmp_save_path;
//开始采集
startGrab();
return true;
}
/// <summary>
/// 停止采集
/// </summary>
public override void stop()
{
if (!IsInit) return;
try
{
if (false == m_bIsDeviceOpen || false == m_bIsGrabbing)
{
return;
}
// ch:标志位设为false | en:Set flag bit false
m_bThreadState = false;
m_hGrabThread.Join();
// ch:停止取流 | en:Stop Acquisition
int nRet = m_cStream.StopAcquisition();
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
//WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low,"Stop acquistion failed, ErrorCode:" + nRet.ToString("X"));
return;
}
m_bIsGrabbing = false;
// ch:关闭流通道 | en:Close stream channel
nRet = m_cStream.CloseStream();
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
//WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low,"Close stream channel failed, ErrorCode:" + nRet.ToString("X"));
}
m_cStream = null;
}
catch
{
return;
}
}
/// <summary>
/// num 因拍了一张后回传的当前已经是1了
/// </summary>
/// <param name="num"></param>
public override void resetScanIndex()
{
scanIndex = 0;//
}
#region private
//开始采集
private void startGrab()
{
if (!m_bIsDeviceOpen)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Please open device first");
return;
}
if (m_bIsGrabbing)
{
return;
}
// ch:获取流通道个数 | en:Get number of stream
uint nStreamNum = 0;
int nRet = m_cDevice.GetNumStreams(ref nStreamNum);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Get streams number failed, ErrorCode:" + nRet.ToString("X"));
return;
}
if (0 == nStreamNum)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "No valid stream channel");
return;
}
// ch:打开流通道(目前只支持单个通道) | en:Open stream(Only a single stream is supported now)
nRet = m_cDevice.OpenStream(0, out m_cStream);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Open stream failed, ErrorCode:" + nRet.ToString("X"));
return;
}
// ch:设置SDK内部缓存数量 | en:Set internal buffer number
const uint nBufNum = 5;
nRet = m_cStream.SetBufferNum(nBufNum);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Set buffer number failed, ErrorCode:" + nRet.ToString("X"));
return;
}
// ch:创建取流线程 | en:Create acquistion thread
m_bThreadState = true;
m_hGrabThread = new Thread(ReceiveThreadProcess);
if (null == m_hGrabThread)
{
m_bThreadState = false;
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Create thread failed");
return;
}
m_hGrabThread.Start();
// ch:开始取流 | en:Start Acquisition
nRet = m_cStream.StartAcquisition();
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
m_bThreadState = false;
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Start acquistion failed, ErrorCode:" + nRet.ToString("X"));
return;
}
m_bIsGrabbing = true;
}
public void setPreviewWin(PictureBox preview_Hwnd)
{
this.previewHwnd = preview_Hwnd;
}
public void ReceiveThreadProcess()
{
CImageProcess cImgProc = new CImageProcess(m_cStream);
MV_FG_BUFFER_INFO stFrameInfo = new MV_FG_BUFFER_INFO(); // ch:图像信息 | en:Frame info
MV_FG_INPUT_IMAGE_INFO stDisplayInfo = new MV_FG_INPUT_IMAGE_INFO(); // ch:显示的图像信息 | en:Display frame info
const uint nTimeout = 1000;
int nRet = 0;
while (m_bThreadState)
{
if (m_bIsGrabbing)
{
// ch:获取一帧图像缓存信息 | en:Get one frame buffer's info
nRet = m_cStream.GetFrameBuffer(ref stFrameInfo, nTimeout);
if (CErrorCode.MV_FG_SUCCESS == nRet)
{
// 用于保存图片
lock (m_LockForSaveImage)
{
if (IntPtr.Zero == m_pDataBuf || m_nDataBufSize < stFrameInfo.nFilledSize)
{
if (IntPtr.Zero != m_pDataBuf)
{
Marshal.FreeHGlobal(m_pDataBuf);
m_pDataBuf = IntPtr.Zero;
}
m_pDataBuf = Marshal.AllocHGlobal((Int32)stFrameInfo.nFilledSize);
if (IntPtr.Zero == m_pDataBuf)
{
m_cStream.ReleaseFrameBuffer(stFrameInfo);
break;
}
m_nDataBufSize = stFrameInfo.nFilledSize;
}
CopyMemory(m_pDataBuf, stFrameInfo.pBuffer, stFrameInfo.nFilledSize);
m_stImageInfo.nWidth = stFrameInfo.nWidth;
m_stImageInfo.nHeight = stFrameInfo.nHeight;
m_stImageInfo.enPixelType = stFrameInfo.enPixelType;
m_stImageInfo.pImageBuf = m_pDataBuf;
m_stImageInfo.nImageBufLen = stFrameInfo.nFilledSize;
//
var imgbuff=SaveImage();
if(imgbuff != null)
{
scanIndex++;
//if (ScanEventPath != null)//Ge用的这个
//{
// string imagpath = $"{this.bmpSavePath}{scanIndex}_dev{_scannerCardIndex}.bmp";
// File.WriteAllBytes(imagpath, imgbuff);
// ScanEventPath?.Invoke(scanIndex, imagpath, _scannerCardIndex);
//}
//else
{
Mat mat = Mat.ImDecode(imgbuff);
//string imagpath = $"{this.bmpSavePath}{scanIndex}_dev{_scannerCardIndex}.bmp";
//File.WriteAllBytes(imagpath, imgbuff);
ScanEvent?.Invoke(scanIndex, mat, _scannerCardIndex);
}
}
}
// 自定义格式不支持显示
if (RemoveCustomPixelFormats(stFrameInfo.enPixelType))
{
m_cStream.ReleaseFrameBuffer(stFrameInfo);
continue;
}
// 配置显示图像的参数
//pictureBox1显示
if (this.previewHwnd != null && IsWindow(this.previewHwnd.Handle))
{
stDisplayInfo.nWidth = stFrameInfo.nWidth;
stDisplayInfo.nHeight = stFrameInfo.nHeight;
stDisplayInfo.enPixelType = stFrameInfo.enPixelType;
stDisplayInfo.pImageBuf = stFrameInfo.pBuffer;
stDisplayInfo.nImageBufLen = stFrameInfo.nFilledSize;
nRet = cImgProc.DisplayOneFrame(previewHwnd.Handle, ref stDisplayInfo);
if (CErrorCode.MV_FG_SUCCESS != nRet)
{
m_cStream.ReleaseFrameBuffer(stFrameInfo);
//this.Invoke(new ShowDisplayError(DisplayError), new object[] { nRet });
break;
}
}
m_cStream.ReleaseFrameBuffer(stFrameInfo);
}
else
{
if (TRIGGER_MODE_ON == m_nTriggerMode)
{
Thread.Sleep(5);
}
}
}
else
{
Thread.Sleep(5);
}
}
}
private byte[] SaveImage(SAVE_IAMGE_TYPE enSaveImageType= SAVE_IAMGE_TYPE.Image_Bmp)
{
int nRet = 0;
lock (m_LockForSaveImage)
{
if (IntPtr.Zero == m_pDataBuf)
return null;// CErrorCode.MV_FG_ERR_NO_DATA;
if (RemoveCustomPixelFormats(m_stImageInfo.enPixelType))
return null;//CErrorCode.MV_FG_ERR_INVALID_VALUE;
uint nMaxImageLen = m_stImageInfo.nWidth * m_stImageInfo.nHeight * 4 + 2048; // 确保存图空间足够,包括图像头
if (IntPtr.Zero == m_pSaveImageBuf || m_nSaveImageBufSize < nMaxImageLen)
{
if (IntPtr.Zero != m_pSaveImageBuf)
{
Marshal.FreeHGlobal(m_pSaveImageBuf);
m_pSaveImageBuf = IntPtr.Zero;
}
m_pSaveImageBuf = Marshal.AllocHGlobal((Int32)nMaxImageLen);
if (IntPtr.Zero == m_pSaveImageBuf)
return null;//CErrorCode.MV_FG_ERR_OUT_OF_MEMORY;
m_nSaveImageBufSize = nMaxImageLen;
}
CImageProcess cImgSave = new CImageProcess(m_cStream);
System.DateTime currentTime = new System.DateTime();
currentTime = System.DateTime.Now;
do
{
if (SAVE_IAMGE_TYPE.Image_Bmp == enSaveImageType)
{
MV_FG_SAVE_BITMAP_INFO stBmpInfo = new MV_FG_SAVE_BITMAP_INFO();
stBmpInfo.stInputImageInfo = m_stImageInfo;
stBmpInfo.pBmpBuf = m_pSaveImageBuf;
stBmpInfo.nBmpBufSize = m_nSaveImageBufSize;
stBmpInfo.enCfaMethod = MV_FG_CFA_METHOD.MV_FG_CFA_METHOD_OPTIMAL;
// ch:保存BMP图像 | en:Save to BMP
nRet = cImgSave.SaveBitmap(ref stBmpInfo);
if (CErrorCode.MV_FG_SUCCESS != nRet)
break;
// ch:将图像数据保存到本地文件 | en:Save image data to local file
byte[] byteData = new byte[stBmpInfo.nBmpBufLen];
Marshal.Copy(stBmpInfo.pBmpBuf, byteData, 0, (int)stBmpInfo.nBmpBufLen);
//保存文件
//string strName = "Image_w" + stBmpInfo.stInputImageInfo.nWidth.ToString() +
// "_h" + stBmpInfo.stInputImageInfo.nHeight.ToString() + "_" + currentTime.Minute.ToString() +
// currentTime.Second.ToString() + currentTime.Millisecond.ToString() + ".bmp";
//FileStream pFile = new FileStream(strName, FileMode.Create);
//if (null == pFile)
//{
// nRet = CErrorCode.MV_FG_ERR_ERROR;
// break;
//}
//pFile.Write(byteData, 0, byteData.Length);
//pFile.Close();
return byteData;
}
else if (SAVE_IAMGE_TYPE.Image_Jpeg == enSaveImageType)
{
MV_FG_SAVE_JPEG_INFO stJpgInfo = new MV_FG_SAVE_JPEG_INFO();
stJpgInfo.stInputImageInfo = m_stImageInfo;
stJpgInfo.pJpgBuf = m_pSaveImageBuf;
stJpgInfo.nJpgBufSize = m_nSaveImageBufSize;
stJpgInfo.nJpgQuality = 80; // JPG编码质量(0-100]
stJpgInfo.enCfaMethod = MV_FG_CFA_METHOD.MV_FG_CFA_METHOD_OPTIMAL;
// ch:保存JPG图像 | en:Save to JPG
nRet = cImgSave.SaveJpeg(ref stJpgInfo);
if (CErrorCode.MV_FG_SUCCESS != nRet)
break;
// ch:将图像数据保存到本地文件 | en:Save image data to local file
byte[] byteData = new byte[stJpgInfo.nJpgBufLen];
Marshal.Copy(stJpgInfo.pJpgBuf, byteData, 0, (int)stJpgInfo.nJpgBufLen);
//保存文件
//string strName = "Image_w" + stJpgInfo.stInputImageInfo.nWidth.ToString() +
// "_h" + stJpgInfo.stInputImageInfo.nHeight.ToString() + "_" + currentTime.Minute.ToString() +
// currentTime.Second.ToString() + currentTime.Millisecond.ToString() + ".jpg";
//FileStream pFile = new FileStream(strName, FileMode.Create);
//if (null == pFile)
//{
// nRet = CErrorCode.MV_FG_ERR_ERROR;
// break;
//}
//pFile.Write(byteData, 0, byteData.Length);
//pFile.Close();
return byteData;
}
else
{
nRet = CErrorCode.MV_FG_ERR_INVALID_PARAMETER;
break;
}
} while (false);
}
return null;//
}
// ch:去除自定义的像素格式 | en:Remove custom pixel formats
private bool RemoveCustomPixelFormats(MV_FG_PIXEL_TYPE enPixelFormat)
{
Int32 nResult = ((int)enPixelFormat) & CUSTOMER_PIXEL_FORMAT;
if (CUSTOMER_PIXEL_FORMAT == nResult)
{
return true;
}
else
{
return false;
}
}
#endregion
public override double[] getFeatureRangeValue(string featureName)
{
switch (featureName)
{
case "ExposureTime":
return new double[2] { 0, 10000 };
case "Gain":
return new double[2] { 0.01, 255 };
default: return new double[0] { };
}
}
public override void getParam()
{
if (!IsInit) return;
CParam cDeviceParam = new CParam(m_cInterface);
MV_FG_FLOATVALUE stParam=new MV_FG_FLOATVALUE();
int nRet = cDeviceParam.GetFloatValue("ExposureTime", ref stParam);
if (nRet == CErrorCode.MV_FG_SUCCESS) ExposureTime = stParam.fCurValue;
nRet = cDeviceParam.GetFloatValue("Gain", ref stParam);
if (nRet == CErrorCode.MV_FG_SUCCESS) Gain = stParam.fCurValue;
nRet = cDeviceParam.GetFloatValue("ResultingFrameRate", ref stParam);
if (nRet == CErrorCode.MV_FG_SUCCESS) ResultingFrameRate = stParam.fCurValue;
}
/// <summary>
///
/// </summary>
/// <param name="exposureTime">曝光</param>
/// <param name="gain">增益</param>
/// <param name="resultingFrameRate">帧率</param>
public override bool setParam(float exposureTime, float gain =-1, float resultingFrameRate =-1)
{
if (!IsInit) return false;
CParam cDeviceParam = new CParam(m_cInterface);
//cDeviceParam.GetXmlFile()
//cDeviceParam.GetNodeAccessMode
//cDeviceParam.GetNodeInterfaceType
bool change = false;
int nRet;
if (exposureTime != ExposureTime && exposureTime != -1)
{
//device.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
//nRet = device.MV_CC_SetFloatValue_NET("ExposureTime", exposureTime);
nRet = cDeviceParam.SetEnumValue("ExposureAuto", (uint)0);
if (CErrorCode.MV_FG_SUCCESS != nRet)
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, "ExposureTime SetEnumValue(\"ExposureAuto\") res=" + nRet);
nRet = cDeviceParam.SetFloatValue("ExposureTime", exposureTime);
if (CErrorCode.MV_FG_SUCCESS != nRet)
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, "ExposureTime SetFloatValue(\"ExposureTime\") res=" + nRet);
change = true;
}
if (gain != Gain && gain != -1)
{
//device.MV_CC_SetEnumValue_NET("GainAuto", 0);
//nRet = device.MV_CC_SetFloatValue_NET("Gain", gain);
cDeviceParam.SetEnumValue("GainAuto", (uint)0);
cDeviceParam.SetFloatValue("Gain", gain);
change = true;
}
if (resultingFrameRate != ResultingFrameRate && resultingFrameRate != -1)
{
cDeviceParam.SetFloatValue("AcquisitionFrameRate", resultingFrameRate);
change = true;
}
//
if (change)
getParam();
return change;
}
public void Dispose()
{
stop();
close();
}
private byte[] bmp2bytes(Bitmap bmp)
{
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); 这两句都可以,至于区别么,下面有解释
ms.Close();
bmp.Dispose();
return bytes;
}
private Bitmap bytes2bmp(byte[] bytes)
{
MemoryStream ms1 = new MemoryStream(bytes);
Bitmap bm = (Bitmap)Image.FromStream(ms1);
ms1.Close();
return bm;
}
public Bitmap read2Bmp(string path)
{
MemoryStream ms = new System.IO.MemoryStream(File.ReadAllBytes(path));
Bitmap bmp = new Bitmap(ms);
ms.Close();
ms.Dispose();
//FileStream fs = new FileStream(path, FileMode.Open);
//byte[] bmpdata = new byte[fs.Length];
//fs.Read(bmpdata, 0, bmpdata.Length);
//Bitmap bmp = new Bitmap(fs);
//fs.Close();
return bmp;
}
}
}