LuJiaYi/HikCamDriver.cs

1304 lines
54 KiB
C#
Raw Normal View History

2024-08-17 18:00:59 +08:00
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using MvCamCtrl.NET;
using OpenCvSharp.Dnn;
using System.Diagnostics;
using HalconDotNet;
using System.Xml.Linq;
namespace GuideGraspSys
{
public class HikCamDriver: CameraBase
{
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
/// <summary>
/// 创建相机集合,存放相机
/// </summary>
MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;
MyCamera.MV_CC_DEVICE_INFO device;
MyCamera hkCamera = new MyCamera();
/// <summary>
/// 抓图回调
/// </summary>
MyCamera.cbOutputExdelegate ImageCallback;
Thread m_hReceiveThread = null;
/// <summary>
/// 异常回调
/// </summary>
MyCamera.cbExceptiondelegate pCallBackFunc;
HObject hPylonImage = new HObject();
List<string> CameraName = new List<string>();
MyCamera.MV_FRAME_OUT _frame = new MyCamera.MV_FRAME_OUT();
readonly ManualResetEvent _snapHandle = new ManualResetEvent(false);
bool _snapFlag = false;
// ch:Bitmap及其像素格式 | en:Bitmap and Pixel Format
Bitmap m_bitmap = null;
PixelFormat m_bitmapPixelFormat = PixelFormat.DontCare;
IntPtr m_ConvertDstBuf = IntPtr.Zero;
UInt32 m_nConvertDstBufLen = 0;
int nRet = MyCamera.MV_OK;
/// <summary>
/// 曝光时间
/// </summary>
public int ExposureTime { get; set; }
/// <summary>
/// 增益
/// </summary>
public int Gain { get; set; }
/// <summary>
/// 帧率
/// </summary>
public int FrameRate { get; set; }
public bool m_bGrabbing = false;
private static Object BufForDriverLock = new Object();
IntPtr m_BufForDriver = IntPtr.Zero;
UInt32 m_nBufSizeForDriver = 0;
MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
public delegate void MatImgTransferDelegate(Mat img);
public event MatImgTransferDelegate OnImgTransfer;
public delegate void BitmapTransferDelegate(Bitmap img);
public event BitmapTransferDelegate OnBitmapTransfer;
public Action<DateTime, Mat> OnHImageOutput { get; set; }
public static Dictionary<string,CameraInfor> allCamera=new Dictionary<string,CameraInfor>();
private CameraInfor currentCam;
public override bool CloserCamera()
{
m_bGrabbing = false;
hkCamera.MV_CC_StopGrabbing_NET();//停止采集
hkCamera.MV_CC_CloseDevice_NET();//关闭设备
hkCamera.MV_CC_DestroyDevice_NET();
return true;
}
/// <summary>
/// 开启硬触发
/// </summary>
/// <returns></returns>
public override bool EncoderGrap()
{
try
{
if (m_bGrabbing)
{
Console.WriteLine("Camera is now Continue Grabing Images");
return false;
}
else
{
// ch:标志位置位true | en:Set position bit true
m_bGrabbing = true;
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
//设置使用硬触发模式
int nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
if (MyCamera.MV_OK != nRet)
{
m_bGrabbing = false;
return false;
}
return true;
}
}
catch (Exception)
{
return false;
}
}
//public override List<string> FindCamera()
//{
// int nRet;
// System.GC.Collect();
// CameraName.Clear();
// nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
// if (0 != nRet)
// {
// Console.WriteLine("Not Find Camera!{0:x8}", nRet);
// return null;
// }
// for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
// {
// MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
// //网口相机
// if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
// {
// IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
// MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
// if (gigeInfo.chUserDefinedName != "")
// {
// Console.WriteLine("GigE:" + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")");
// CameraName.Add("GigE:" + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")");
// }
// else
// {
// Console.WriteLine("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")");
// CameraName.Add("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")");
// }
// }
// else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
// {
// IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0);
// MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
// if (usbInfo.chUserDefinedName != "")
// {
// Console.WriteLine("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")");
// CameraName.Add("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")");
// }
// else
// {
// Console.WriteLine("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")");
// CameraName.Add("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")");
// }
// }
// }
// if (m_pDeviceList.nDeviceNum == 0)
// {
// Console.WriteLine("未能找到USB或者网线接口的相机", 0);
// return null;
// }
// return CameraName;
//}
public Dictionary<string, CameraInfor> EnumDevice()
{
System.GC.Collect();//强制对所有代进行及时垃圾回收
m_pDeviceList.nDeviceNum = 0; //初始化信息列表
int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
if (0 != nRet)
{
return null;
}
allCamera.Clear(); //清空设备列表
CameraInfor cameraInfor;
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
{
MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取第i个相机句柄的相机信息
cameraInfor = new CameraInfor();
cameraInfor.pDeviceInfo = m_pDeviceList.pDeviceInfo[i];//获取相机句柄
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
{
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));//将通用相机信息结构体转化为Gige相机结构体
UInt32 nNetIp1 = (gigeInfo.nNetExport & 0xFF000000) >> 24;
UInt32 nNetIp2 = (gigeInfo.nNetExport & 0x00FF0000) >> 16;
UInt32 nNetIp3 = (gigeInfo.nNetExport & 0x0000FF00) >> 8;
UInt32 nNetIp4 = (gigeInfo.nNetExport & 0x000000FF);
// ch:显示IP | en:Display IP
UInt32 nIp1 = (gigeInfo.nCurrentIp & 0xFF000000) >> 24;
UInt32 nIp2 = (gigeInfo.nCurrentIp & 0x00FF0000) >> 16;
UInt32 nIp3 = (gigeInfo.nCurrentIp & 0x0000FF00) >> 8;
UInt32 nIp4 = (gigeInfo.nCurrentIp & 0x000000FF);
cameraInfor.serialNumber = gigeInfo.chSerialNumber;
cameraInfor.userDefinedName = gigeInfo.chUserDefinedName;
cameraInfor.manufacturerName = gigeInfo.chManufacturerName;
cameraInfor.modelName = gigeInfo.chModelName;
cameraInfor.deviceType = "GEV"; //千兆网工业相机技术之GigE VisionGEV
cameraInfor.deviceIPAdd = nIp1.ToString() + "." + nIp2.ToString() + "." + nIp3.ToString() + "." + nIp4.ToString();
allCamera.Add(cameraInfor.userDefinedName, cameraInfor);
}
else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
{
MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO));
cameraInfor.serialNumber = usbInfo.chSerialNumber;
cameraInfor.userDefinedName = usbInfo.chUserDefinedName;
cameraInfor.manufacturerName = usbInfo.chManufacturerName;
cameraInfor.modelName = usbInfo.chModelName;
cameraInfor.deviceType = "U3V";
allCamera.Add(cameraInfor.deviceIPAdd, cameraInfor);
}
}
return allCamera;
}
/// <summary>
/// 根据相机序列号开启相机
/// </summary>
/// <param name="CameraName"></param>
/// int cameraIndex
/// <returns></returns>
public override bool OpenCamera(string userDefinedName, IntPtr hWnd)
{
int nRet = 0;
currentCam = allCamera[userDefinedName];
//m_pDeviceList.pDeviceInfo[cameraIndex]
device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(allCamera[userDefinedName].pDeviceInfo, typeof(MyCamera.MV_CC_DEVICE_INFO));
IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
if (null == hkCamera)
{
hkCamera = new MyCamera();
if (null == hkCamera)
{
return false;
}
}
for (int i = 0; i < 10; i++)
{
nRet = hkCamera.MV_CC_CreateDevice_NET(ref device);
if (MyCamera.MV_OK != nRet)
{
Thread.Sleep(1);
if (i == 9) Console.WriteLine("创建相机失败!{0:x8}", nRet);
continue;
}
nRet = hkCamera.MV_CC_OpenDevice_NET();
if (MyCamera.MV_OK != nRet)
{
hkCamera.MV_CC_DestroyDevice_NET();
Thread.Sleep(10);
if (i == 9) Console.WriteLine("打开相机失败!{0:x8}", nRet);
}
else
{
break;
}
}
//探测网络最佳包大小只对gige相机有效
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
{
int nPacketSize = hkCamera.MV_CC_GetOptimalPacketSize_NET();
if (nPacketSize > 0)
{
nRet = hkCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
if (nRet != MyCamera.MV_OK)
{
Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);
}
}
else
{
Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize);
}
}
SetTriggerMode(true);
SetSoftTrigger(true);
//注册断线重连回调函数
nRet = hkCamera.MV_CC_RegisterExceptionCallBack_NET(pCallBackFunc, IntPtr.Zero);
if (MyCamera.MV_OK != nRet)
{
return false;
}
GC.KeepAlive(pCallBackFunc);
//注册图像回调函数
//ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
//nRet = hkCamera.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
if (MyCamera.MV_OK != nRet)
{
Console.WriteLine("Register image callback failed!");
return false;
}
// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
hkCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
//设置开启触发模式
nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
//设置开启软触发模式
//hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
//使用软触发命令
//nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
if (MyCamera.MV_OK != nRet)
{
m_bGrabbing = false;
return false;
}
//开始采集
// nRet = hkCamera.MV_CC_StartGrabbing_NET();
if (MyCamera.MV_OK != nRet)
{
Console.WriteLine("开启相机采集失败! {0:x8}", nRet);
return false;
}
return true;
}
/// <summary>
/// 设置触发模式
/// </summary>
/// <param name="isTrigger">触发模式true连续采集模式false</param>
public void SetTriggerMode(bool isTrigger)
{
if (isTrigger)
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
}
else
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
}
}
/// <summary>
/// 设置软触发
/// </summary>
/// <param name="trigBySoft"></param>
public void SetSoftTrigger(bool trigBySoft)
{
if (trigBySoft)
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
}
else
{
//外部触发源Line0~Line3默认用Line0
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
}
}
/// </summary>
/// <returns></returns>
//public override bool OneGrap()
//{
// try
// {
// if (m_bGrabbing)
// {
// Console.WriteLine("Camera is now Continue Grabing Images");
// return false;
// }
// else
// {
// // ch:标志位置位true | en:Set position bit true
// //m_bGrabbing = true;
// int nRet;
// MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
// //设置开启触发模式
// nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
// //设置开启软触发模式
// nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
// //使用软触发命令
// nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
// if (MyCamera.MV_OK != nRet)
// {
// throw new Exception($"相机拍照触发失败:{nRet}");
// }
// //nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000);
// //nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo);
// if (MyCamera.MV_OK != nRet)
// {
// m_bGrabbing = false;
// return false;
// }
// else
// {
// //if (frameInfo.pBufAddr != IntPtr.Zero)
// //{
// if (nRet == MyCamera.MV_OK)
// {
// var pFrameInfo = frameInfo.stFrameInfo;
// //himg.GenImage1("byte", pFrameInfo.nWidth, pFrameInfo.nHeight, frameInfo.pBufAddr);
// Mat mat = Mat.FromPixelData(pFrameInfo.nWidth, pFrameInfo.nHeight, MatType.CV_8UC3, frameInfo.pBufAddr);
// //Bitmap a = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
// //OnDeliverImg?.Invoke(_mat);
// Cv2.ImWrite("test.jpg", mat);
// OnImgTransfer?.Invoke(mat);
// }
// //}
// }
// // HeventSlim.Wait();
// return true;
// }
// }
// catch (Exception)
// {
// return false;
// }
//}
bool IsGrabImg;
public void GrabImg()
{
IsGrabImg = true;
int nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
//nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref frameInfo,10);
//nRet = m_MyCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo);
if (MyCamera.MV_OK != nRet)
{
//ShowErrorMsg("Trigger Software Fail!", nRet);
}
}
public void StartGarb(IntPtr handle)
{
int nRet;
nRet = NecessaryOperBeforeGrab();
m_bGrabbing = true;
IsGrabImg = false;
m_hReceiveThread = new Thread(new ParameterizedThreadStart(ReceiveThreadProcess));
m_hReceiveThread.Start(handle);
m_stFrameInfo.nFrameLen = 0;
m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;
// nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
//设置开启软触发模式
//nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
// ch:开始采集 | en:Start Grabbing
nRet = hkCamera.MV_CC_StartGrabbing_NET();
if (MyCamera.MV_OK != nRet)
{
m_bGrabbing = false;
m_hReceiveThread.Join();
//ShowErrorMsg("Start Grabbing Fail!", nRet);
return;
}
}
//public void StopGrabbing()
//{
// int nRet = hkCamera.MV_CC_StopGrabbing_NET();
// if (nRet != MyCamera.MV_OK)
// {
// //ShowAlarm(string.Format("相机{0}结束采集失败,错误代码:{1}", m_Name, nRet));
// }
//}
public void ReceiveThreadProcess(object handle)
{
MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT();
MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();
MyCamera.MV_PIXEL_CONVERT_PARAM stConvertInfo = new MyCamera.MV_PIXEL_CONVERT_PARAM();
int nRet = MyCamera.MV_OK;
while (m_bGrabbing)
{
nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000);
if (nRet == MyCamera.MV_OK)
{
lock (BufForDriverLock)
{
if (m_BufForDriver == IntPtr.Zero || stFrameInfo.stFrameInfo.nFrameLen > m_nBufSizeForDriver)
{
if (m_BufForDriver != IntPtr.Zero)
{
Marshal.Release(m_BufForDriver);
m_BufForDriver = IntPtr.Zero;
}
m_BufForDriver = Marshal.AllocHGlobal((Int32)stFrameInfo.stFrameInfo.nFrameLen);
if (m_BufForDriver == IntPtr.Zero)
{
return;
}
m_nBufSizeForDriver = stFrameInfo.stFrameInfo.nFrameLen;
}
m_stFrameInfo = stFrameInfo.stFrameInfo;
CopyMemory(m_BufForDriver, stFrameInfo.pBufAddr, stFrameInfo.stFrameInfo.nFrameLen);
stConvertInfo.nWidth = stFrameInfo.stFrameInfo.nWidth;
stConvertInfo.nHeight = stFrameInfo.stFrameInfo.nHeight;
stConvertInfo.enSrcPixelType = stFrameInfo.stFrameInfo.enPixelType;
stConvertInfo.pSrcData = stFrameInfo.pBufAddr;
stConvertInfo.nSrcDataLen = stFrameInfo.stFrameInfo.nFrameLen;
stConvertInfo.pDstBuffer = m_ConvertDstBuf;
stConvertInfo.nDstBufferSize = m_nConvertDstBufLen;
if (PixelFormat.Format8bppIndexed == m_bitmap.PixelFormat)
{
stConvertInfo.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
hkCamera.MV_CC_ConvertPixelType_NET(ref stConvertInfo);
}
else
{
stConvertInfo.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed;
hkCamera.MV_CC_ConvertPixelType_NET(ref stConvertInfo);
}
// ch:保存Bitmap数据 | en:Save Bitmap Data
BitmapData bitmapData = m_bitmap.LockBits(new Rectangle(0, 0, stConvertInfo.nWidth, stConvertInfo.nHeight), ImageLockMode.ReadWrite, m_bitmap.PixelFormat);
CopyMemory(bitmapData.Scan0, stConvertInfo.pDstBuffer, (UInt32)(bitmapData.Stride * m_bitmap.Height));
m_bitmap.UnlockBits(bitmapData);
}
if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType))
{
hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
continue;
}
nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
if (IsGrabImg)
{
if (MyCamera.MV_OK == nRet)
{
if (stFrameInfo.pBufAddr != IntPtr.Zero)
{
stDisplayInfo.hWnd = (IntPtr)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;
hkCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);
//nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
var pFrameInfo = stFrameInfo.stFrameInfo;
Mat ab = new Mat(pFrameInfo.nHeight, pFrameInfo.nWidth, MatType.CV_8UC3, stFrameInfo.pBufAddr);
//OnImgTransfer?.Invoke(ab);
OnHImageOutput?.Invoke(DateTime.Now, ab);
//Cv2.ImWrite("test.jpg", ab);
}
}
}
}
else
{
}
}
}
public void ConvertToImage(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
{
int nRet;
//HObject img = new HObject();
Mat matImag = new Mat();
//Bitmap bitmap = new Bitmap();
IntPtr pImageBuf = IntPtr.Zero;
int nImageBufSize = 0;
//Bitmap cameraImg;
IntPtr pTemp = IntPtr.Zero;
if (IsColorPixelFormat(pFrameInfo.enPixelType))
{
//cameraImg = new Bitmap(pFrameInfo.nWidth, pFrameInfo.nHeight, pFrameInfo.nWidth * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb,pData);
//bmp.Save("1.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
{
pTemp = pData;
}
else
{
if (IntPtr.Zero == pImageBuf || nImageBufSize < (pFrameInfo.nWidth * pFrameInfo.nHeight * 3))
{
if (pImageBuf != IntPtr.Zero)
{
Marshal.FreeHGlobal(pImageBuf);
pImageBuf = IntPtr.Zero;
}
pImageBuf = Marshal.AllocHGlobal((int)pFrameInfo.nWidth * pFrameInfo.nHeight * 3);
if (IntPtr.Zero == pImageBuf)
{
Console.WriteLine("图像采集为空");
return;
}
nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight * 3;
}
MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();
stPixelConvertParam.pSrcData = pData;//源数据
stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度
stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度
stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式
stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen;
stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
nRet = hkCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
if (MyCamera.MV_OK != nRet)
{
Console.WriteLine("图像转换异常");
return;
}
pTemp = stPixelConvertParam.pDstBuffer;
}
try
{
HOperatorSet.GenImageInterleaved(out hPylonImage, (HTuple)pTemp, (HTuple)"rgb", (HTuple)pFrameInfo.nWidth, (HTuple)pFrameInfo.nHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
return;
}
}
else if (IsMonoPixelFormat(pFrameInfo.enPixelType))
{
if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
{
pTemp = pData;
}
else
{
if (IntPtr.Zero == pImageBuf || nImageBufSize < (pFrameInfo.nWidth * pFrameInfo.nHeight))
{
if (pImageBuf != IntPtr.Zero)
{
Marshal.FreeHGlobal(pImageBuf);
pImageBuf = IntPtr.Zero;
}
pImageBuf = Marshal.AllocHGlobal((int)pFrameInfo.nWidth * pFrameInfo.nHeight);
if (IntPtr.Zero == pImageBuf)
{
Console.WriteLine("图像采集为空");
return;
}
nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight;
}
MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();
stPixelConvertParam.pSrcData = pData;//源数据
stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度
stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度
stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式
stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen;
stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
nRet = hkCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
if (MyCamera.MV_OK != nRet)
{
Console.WriteLine("图像转换异常");
return;
}
pTemp = stPixelConvertParam.pDstBuffer; ;
}
try
{
//cameraImg = new Bitmap();
// HOperatorSet.GenImage1Extern(out hPylonImage, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pTemp, IntPtr.Zero);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
return;
}
}
else
{
Console.WriteLine("采集图像格式错误,不为彩色和黑白图像");
return;
}
try
{
//GetImage(hPylonImage);//调用相机基类的函数,用于传出变量
//hPylonImage.Dispose();
m_bGrabbing = false;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return;
}
}
private Boolean IsMono(UInt32 enPixelType)
{
switch (enPixelType)
{
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono1p:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono2p:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono4p:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8_Signed:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono14:
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono16:
return true;
default:
return false;
}
}
private Int32 NecessaryOperBeforeGrab()
{
// ch:取图像宽 | en:Get Iamge Width
MyCamera.MVCC_INTVALUE_EX stWidth = new MyCamera.MVCC_INTVALUE_EX();
int nRet = hkCamera.MV_CC_GetIntValueEx_NET("Width", ref stWidth);
if (MyCamera.MV_OK != nRet)
{
//ShowErrorMsg("Get Width Info Fail!", nRet);
return nRet;
}
// ch:取图像高 | en:Get Iamge Height
MyCamera.MVCC_INTVALUE_EX stHeight = new MyCamera.MVCC_INTVALUE_EX();
nRet = hkCamera.MV_CC_GetIntValueEx_NET("Height", ref stHeight);
if (MyCamera.MV_OK != nRet)
{
//ShowErrorMsg("Get Height Info Fail!", nRet);
return nRet;
}
// ch:取像素格式 | en:Get Pixel Format
MyCamera.MVCC_ENUMVALUE stPixelFormat = new MyCamera.MVCC_ENUMVALUE();
nRet = hkCamera.MV_CC_GetEnumValue_NET("PixelFormat", ref stPixelFormat);
if (MyCamera.MV_OK != nRet)
{
//ShowErrorMsg("Get Pixel Format Fail!", nRet);
return nRet;
}
// ch:设置bitmap像素格式申请相应大小内存 | en:Set Bitmap Pixel Format, alloc memory
if ((Int32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined == stPixelFormat.nCurValue)
{
//ShowErrorMsg("Unknown Pixel Format!", MyCamera.MV_E_UNKNOW);
return MyCamera.MV_E_UNKNOW;
}
else if (IsMono(stPixelFormat.nCurValue))
{
m_bitmapPixelFormat = PixelFormat.Format8bppIndexed;
if (IntPtr.Zero != m_ConvertDstBuf)
{
Marshal.Release(m_ConvertDstBuf);
m_ConvertDstBuf = IntPtr.Zero;
}
// Mono8为单通道
m_nConvertDstBufLen = (UInt32)(stWidth.nCurValue * stHeight.nCurValue);
m_ConvertDstBuf = Marshal.AllocHGlobal((Int32)m_nConvertDstBufLen);
if (IntPtr.Zero == m_ConvertDstBuf)
{
//ShowErrorMsg("Malloc Memory Fail!", MyCamera.MV_E_RESOURCE);
return MyCamera.MV_E_RESOURCE;
}
}
else
{
m_bitmapPixelFormat = PixelFormat.Format24bppRgb;
if (IntPtr.Zero != m_ConvertDstBuf)
{
Marshal.FreeHGlobal(m_ConvertDstBuf);
m_ConvertDstBuf = IntPtr.Zero;
}
// RGB为三通道
m_nConvertDstBufLen = (UInt32)(3 * stWidth.nCurValue * stHeight.nCurValue);
m_ConvertDstBuf = Marshal.AllocHGlobal((Int32)m_nConvertDstBufLen);
if (IntPtr.Zero == m_ConvertDstBuf)
{
//ShowErrorMsg("Malloc Memory Fail!", MyCamera.MV_E_RESOURCE);
return MyCamera.MV_E_RESOURCE;
}
}
// 确保释放保存了旧图像数据的bitmap实例用新图像宽高等信息new一个新的bitmap实例
if (null != m_bitmap)
{
m_bitmap.Dispose();
m_bitmap = null;
}
m_bitmap = new Bitmap((Int32)stWidth.nCurValue, (Int32)stHeight.nCurValue, m_bitmapPixelFormat);
// ch:Mono8格式设置为标准调色板 | en:Set Standard Palette in Mono8 Format
if (PixelFormat.Format8bppIndexed == m_bitmapPixelFormat)
{
ColorPalette palette = m_bitmap.Palette;
for (int i = 0; i < palette.Entries.Length; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
m_bitmap.Palette = palette;
}
return MyCamera.MV_OK;
}
/// <summary>
/// 相机重连开启
/// </summary>
/// <param name="CameraName"></param>
/// <returns></returns>
public override bool ReconnectCamera(string CameraName)
{
CloserCamera();
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
{
device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
if (gigeInfo.chSerialNumber == CameraName)
{
break;
}
}
int index = 0;
while (true)
{
int nRet = hkCamera.MV_CC_CreateDevice_NET(ref device);
index++;
if (index > 1000)
{
Console.WriteLine("相机重连超时,请检查相机安装");
nRet = -1;
break;
}
if (MyCamera.MV_OK != nRet)
{
Thread.Sleep(5);
continue;
}
nRet = hkCamera.MV_CC_OpenDevice_NET();
if (MyCamera.MV_OK != nRet)
{
Thread.Sleep(5);
hkCamera.MV_CC_DestroyDevice_NET();
continue;
}
else
{
if (MyCamera.MV_OK != nRet)
{
Thread.Sleep(5);
hkCamera.MV_CC_DestroyDevice_NET();
continue;
}
break;
}
}
return true;
}
void ImageCallbackFunc(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
{
//Console.WriteLine("Get one frame: Width[" + Convert.ToString(pFrameInfo.nWidth) + "] , Height[" + Convert.ToString(pFrameInfo.nHeight)
// + "] , FrameNum[" + Convert.ToString(pFrameInfo.nFrameNum) + "]");
ConvertToImage(pData, ref pFrameInfo, pUser);
}
public Action<Mat> OnDeliverImg { get; set; }
public void Snapshot()
{
Stopwatch sw = new Stopwatch();
sw.Start();
// ImageSet set = new ImageSet();
// set.SnapshotCount = SnapshotCount;
// set.SnapshotFileName = SnapshotFileNames;
//InitialImageSet(set);
MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
nRet = MyCamera.MV_OK;
if (true)
{
// ch: 触发命令 || en: Trigger command
nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
if (MyCamera.MV_OK != nRet)
{
throw new Exception($"相机拍照触发失败:{nRet}");
}
nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000);
nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo);
}
else
{
_snapHandle.Reset();
_snapFlag = true;
_snapHandle.WaitOne();
//lock (_imgCallBackLock)
{
frameInfo.stFrameInfo = _frame.stFrameInfo;
frameInfo.pBufAddr = _frame.pBufAddr;
}
}
// ch:获取一帧图像 | en:Get one image
if (MyCamera.MV_OK == nRet)
{
if (frameInfo.pBufAddr != IntPtr.Zero)
{
if (nRet == MyCamera.MV_OK)
{
var pFrameInfo = frameInfo.stFrameInfo;
HImage hImage = new HImage();
hImage.GenImage1("byte", pFrameInfo.nWidth, pFrameInfo.nHeight, frameInfo.pBufAddr);
Mat mat = new Mat();
Bitmap a = hImage.ConvertHImageToBitmap();
OnBitmapTransfer?.Invoke(a);
}
}
}
else
{
throw new Exception($"Grap Image Failed:{nRet:x8}");
}
sw.Stop();
//LogAsync(DateTime.Now, LogLevel.Information, $"取像耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 转化像素为Bit图像
/// </summary>
/// <param name="pData"></param>
/// <param name="pFrameInfo"></param>
public Bitmap GetBitmap(int nWidth, int nHeight, int nBpp, byte[] DataBuf, int nCompress = 1)
{
int nNewH = nHeight / nCompress;
int nNewW = nWidth / nCompress;
Bitmap BitmapImage = new Bitmap(nNewW, nNewH, PixelFormat.Format24bppRgb);
BitmapData srcBmpData =
BitmapImage.LockBits(
new Rectangle(0, 0, BitmapImage.Width, BitmapImage.Height),
ImageLockMode.ReadWrite, BitmapImage.PixelFormat);
switch (nBpp)
{
case 0:
unsafe
{
byte* psrcBuffer = (byte*)srcBmpData.Scan0.ToPointer();
int nIndex = 0;
for (int i = 0; i < nHeight; i += nCompress)
{
for (int j = 0; j < nWidth; j += nCompress)
{
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
}
}
}
break;
case 1:
unsafe
{
byte* psrcBuffer = (byte*)srcBmpData.Scan0.ToPointer();
int nCount = nWidth * nHeight;
int nStep = nCount * 2;
int nIndex = 0;
for (int i = 0; i < nHeight; i += nCompress)
{
for (int j = 0; j < nWidth; j += nCompress)
{
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j + nStep];
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j + nCount];
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
}
}
}
break;
}
BitmapImage.UnlockBits(srcBmpData);
return BitmapImage;
}
public void SetHeartBeatTime(uint value)
{
try
{
//判断是否是网口相机
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
{
hkCamera.MV_CC_SetHeartBeatTimeout_NET(value);
}
}
catch (Exception)
{
}
}
public override bool SetExpoureTime(int ExposureTime)
{
try
{
hkCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
int nRet = hkCamera.MV_CC_SetFloatValue_NET("ExposureTime", ExposureTime);
if (nRet != MyCamera.MV_OK)
{
return false;
}
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 判断是否为彩色图像
/// </summary>
/// <param name="mvGvspPixelType"></param>
/// <returns></returns>
private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
{
switch (enType)
{
case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
return true;
default:
return false;
}
}
private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
{
switch (enType)
{
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
return true;
default:
return false;
}
}
private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat)
{
Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000));
if (0x80000000 == nResult)
{
return true;
}
else
{
return false;
}
}
public void SetTriggerMode()
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
}
public void SetTriggerModeON()
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
}
public void SetTriggerSource()
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
}
public void SetTriggerSourceLine0()
{
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
}
public void SetTriggerMode1()
{
int nRet;
nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
//设置开启软触发模式
nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
}
}
public static class HalconHelper
{
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
public static Bitmap ConvertHImageToBitmap(this HObject hImage)
{
HOperatorSet.CountChannels(hImage, out HTuple chanels);
if (chanels.I == 1)
{
return hImage.ConvertHImageTo8GrayBitmap();
}
else
{
return hImage.ConvertHImageToRGBBitmap();
// return hImage.HObject2BitmapRGB();
}
}
public static Bitmap ConvertHImageTo8GrayBitmap(this HObject hImage)
{
try
{
HTuple type, width, height, pointer;
HOperatorSet.GetImagePointer1(hImage, out pointer, out type, out width, out height);
Bitmap bmp = new Bitmap(width.I, height.I, PixelFormat.Format8bppIndexed);
ColorPalette pal = bmp.Palette;
for (int i = 0; i <= 255; i++)
{
pal.Entries[i] = Color.FromArgb(255, i, i, i);
}
bmp.Palette = pal;
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
if (width % 4 == 0)
{
CopyMemory(bitmapData.Scan0, (IntPtr)pointer.D, (uint)(bitmapData.Stride * height.I));
}
else
{
Parallel.For(0, height.I, h =>
{
CopyMemory(bitmapData.Scan0 + h * bitmapData.Stride, (IntPtr)(pointer.D + h * width.I), (uint)width.I);
});
}
bmp.UnlockBits(bitmapData);
return bmp;
}
catch (Exception ex)
{
return null;
}
}
public static Bitmap ConvertHImageToRGBBitmap(this HObject hImage)
{
try
{
HOperatorSet.GetImagePointer3(hImage, out HTuple pointRed, out HTuple pointGreen, out HTuple pointBlue, out HTuple type, out HTuple width, out HTuple height);
Bitmap image = new Bitmap(width.I, height.I, PixelFormat.Format24bppRgb);
BitmapData imageData = image.LockBits(new Rectangle(0, 0, width.I, height.I), ImageLockMode.ReadWrite, image.PixelFormat);
IntPtr pR = (IntPtr)pointRed.D;
IntPtr pG = (IntPtr)pointGreen.D;
IntPtr pB = (IntPtr)pointBlue.D;
Parallel.For(0, imageData.Height, h =>
{
Parallel.For(0, imageData.Width, w =>
{
int dest = h * imageData.Stride + w * 3;
int source = h * imageData.Width + w;
Marshal.WriteByte(imageData.Scan0, dest, Marshal.ReadByte(pB, source));
Marshal.WriteByte(imageData.Scan0, dest + 1, Marshal.ReadByte(pG, source));
Marshal.WriteByte(imageData.Scan0, dest + 2, Marshal.ReadByte(pR, source));
});
});
image.UnlockBits(imageData);
return image;
}
catch (Exception exc)
{
return null;
}
}
}
public class CameraInfor
{
public string userDefinedName { get; set; } //用户定义的名字
public string serialNumber { get; set; } //序列号
public string deviceIPAdd { get; set; } //设备IP地址
public string manufacturerName { get; set; }//制造厂商名
public string modelName { get; set; } //型号名称
public string deviceType { get; set; } //型号名称
public IntPtr pDeviceInfo; //相机句柄
public float ExposureTime { get; set; } //曝光时间
public float Gain { get; set; } //增益
public float ResultingFrameRate { get; set; } //帧率
public bool isOpenTriggerMode { get; set; } //是否打开触发方式
}
public class ASCameraParamInfor
{
/// <summary>
/// 曝光时间
/// </summary>
public float ExposureTime { get; set; }
/// <summary>
/// 增益
/// </summary>
public float Gain { get; set; }
/// <summary>
/// 获取帧率
/// </summary>
public float FrameRate { get; set; }
}
}