LuJiaYi/HikCamDriver.cs
2024-08-17 18:00:59 +08:00

1304 lines
54 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 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; }
}
}