562 lines
24 KiB
C#
562 lines
24 KiB
C#
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 IKapBoardClassLibrary;
|
||
using LeatherApp.Interface;
|
||
using Newtonsoft.Json.Linq;
|
||
using OpenCvSharp;
|
||
using OpenCvSharp.Dnn;
|
||
using ErrorCode = IKapBoardClassLibrary.ErrorCode;
|
||
|
||
namespace LeatherApp.Device
|
||
{
|
||
public class CamerCardDev2 : 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);
|
||
[DllImport("User32.dll")]
|
||
public extern static System.IntPtr GetDC(System.IntPtr hWnd);
|
||
|
||
[DllImport("user32.dll")]
|
||
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||
|
||
//显示图像控件句柄
|
||
private PictureBox previewHwnd = null;
|
||
//
|
||
// 采集卡设备句柄。
|
||
public IntPtr m_hBoard = new IntPtr(-1);
|
||
// 当前帧索引。
|
||
public int m_nCurFrameIndex = 0;
|
||
// 图像缓冲区申请的帧数。
|
||
public int m_nTotalFrameCount = 1;
|
||
// 保存图像的文件名。
|
||
public string m_strFileName = "C:\\CSharpImage.bmp";
|
||
|
||
//
|
||
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 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;//相机索引(一个采集卡上可插多个相机)
|
||
|
||
public CamerCardDev2( )
|
||
{
|
||
}
|
||
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 ret = (int)ErrorCode.IK_RTN_OK;
|
||
uint nPCIeDevCount = 0;
|
||
StringBuilder resourceName;
|
||
uint resourceNameSize = 0;
|
||
IKapBoard.IKAPERRORINFO tIKei = new IKapBoard.IKAPERRORINFO();
|
||
|
||
// 获取连接的采集卡数量。
|
||
ret = IKapBoard.IKapGetBoardCount((int)BoardType.IKBoardPCIE, ref nPCIeDevCount);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 当没有连接的采集卡时。
|
||
if (nPCIeDevCount == 0 || nPCIeDevCount< cardIndex+1)
|
||
{
|
||
WarningEvent?.Invoke(WarningEnum.High, "Get board count 0");
|
||
return false;
|
||
}
|
||
|
||
// 获取采集卡名称。
|
||
for (uint i = 0; i < nPCIeDevCount; i++)
|
||
{
|
||
resourceNameSize = 0;
|
||
resourceName = new StringBuilder(0);
|
||
IKapBoard.IKapGetBoardName((uint)BoardType.IKBoardPCIE, i, resourceName, ref resourceNameSize);
|
||
IKapBoard.IKapGetLastError(ref tIKei, true);
|
||
if (tIKei.uErrorCode == (uint)ErrorCode.IKStatus_BufferTooSmall)
|
||
{
|
||
resourceName = new StringBuilder((int)resourceNameSize);
|
||
IKapBoard.IKapGetBoardName((uint)BoardType.IKBoardPCIE, i, resourceName, ref resourceNameSize);
|
||
}
|
||
IKapBoard.IKapGetLastError(ref tIKei, true);
|
||
if (tIKei.uErrorCode != (uint)ErrorCode.IKStatus_Success)
|
||
{
|
||
WarningEvent?.Invoke(WarningEnum.High, "Get Device Name Fail. Error Code:"+tIKei.uErrorCode);
|
||
return false;
|
||
}
|
||
string sMesg = string.Concat("PCIE Device- ", i.ToString("d"), "\nName: ", resourceName);
|
||
|
||
}
|
||
|
||
// 打开采集卡。
|
||
//
|
||
// Open frame grabber.
|
||
m_hBoard = IKapBoard.IKapOpen((int)BoardType.IKBoardPCIE, 0);//采集卡索引0-n
|
||
if (m_hBoard.Equals(-1))
|
||
{
|
||
WarningEvent?.Invoke(WarningEnum.High, "Open device failure!");
|
||
return false;
|
||
}
|
||
|
||
// 导入配置文件。
|
||
string configFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DevCfg\\"+ Config.CarmerConfigFilePath;
|
||
if (!File.Exists(configFileName))
|
||
{
|
||
WarningEvent?.Invoke(WarningEnum.High, "Fail to get configuration, using default setting!");
|
||
return false;
|
||
}
|
||
ret = IKapBoard.IKapLoadConfigurationFromFile(m_hBoard, configFileName);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 设置图像缓冲区帧数。
|
||
//
|
||
// Set frame count of buffer.
|
||
ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_FRAME_COUNT, m_nTotalFrameCount);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 设置超时时间。
|
||
//
|
||
// Set time out time.
|
||
int timeout = -1;
|
||
ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_TIME_OUT, timeout);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 设置采集模式。
|
||
//
|
||
// Set grab mode.
|
||
int grab_mode = (int)GrabMode.IKP_GRAB_NON_BLOCK;//非阻塞StartGrab
|
||
ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_GRAB_MODE, grab_mode);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 设置传输模式。
|
||
//
|
||
// Set transfer mode.
|
||
int transfer_mode = (int)FrameTransferMode.IKP_FRAME_TRANSFER_SYNCHRONOUS_NEXT_EMPTY_WITH_PROTECT;
|
||
ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_FRAME_TRANSFER_MODE, transfer_mode);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 注册回调函数
|
||
//
|
||
// Register callback functions.
|
||
OnGrabStartProc = new IKapCallBackProc(OnGrabStartFunc);
|
||
ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStart, Marshal.GetFunctionPointerForDelegate(OnGrabStartProc), m_hBoard);
|
||
CheckIKapBoard(ret);
|
||
OnFrameReadyProc = new IKapCallBackProc(OnFrameReadyFunc);
|
||
ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameReady, Marshal.GetFunctionPointerForDelegate(OnFrameReadyProc), m_hBoard);
|
||
CheckIKapBoard(ret);
|
||
OnFrameLostProc = new IKapCallBackProc(OnFrameLostFunc);
|
||
ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameLost, Marshal.GetFunctionPointerForDelegate(OnFrameLostProc), m_hBoard);
|
||
CheckIKapBoard(ret);
|
||
OnTimeoutProc = new IKapCallBackProc(OnTimeoutFunc);
|
||
ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_TimeOut, Marshal.GetFunctionPointerForDelegate(OnTimeoutProc), m_hBoard);
|
||
CheckIKapBoard(ret);
|
||
OnGrabStopProc = new IKapCallBackProc(OnGrabStopFunc);
|
||
ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStop, Marshal.GetFunctionPointerForDelegate(OnGrabStopProc), m_hBoard);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 设置行触发参数。
|
||
//SetLineTrigger();
|
||
//
|
||
getParam();
|
||
|
||
IsInit = true;
|
||
//timer.Elapsed += Timer_Elapsed;
|
||
//timer.Interval = 100;
|
||
//timer.Enabled = true;
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
WarningEvent?.Invoke(WarningEnum.High, ex.Message);
|
||
return false;
|
||
}
|
||
}
|
||
public override void close()
|
||
{
|
||
if (!IsInit) return;
|
||
|
||
try
|
||
{
|
||
IsInit = false;
|
||
// 清除回调函数。
|
||
UnRegisterCallback();
|
||
|
||
// 关闭设备。
|
||
CloseDevice();
|
||
}
|
||
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;
|
||
//开始采集
|
||
//第二个参数 nFrameCount 表示希望 IKapBoardClassLibrary 采集的帧数。
|
||
//如果 nFrameCount = 1,IKapBoardClassLibrary 会从相机中采集一帧图像;
|
||
//如果 nFrameCount = N 且 N> 1,则 IKapBoardClassLibrary 从相机中采集连续的 N 帧图 像;
|
||
//如果 nFrameCount = 0,则 IKapBoardClassLibrary 开始连续采集图像。
|
||
var ret = IKapBoard.IKapStartGrab(m_hBoard, 0);
|
||
return ret == (int)ErrorCode.IK_RTN_OK;
|
||
}
|
||
/// <summary>
|
||
/// 停止采集
|
||
/// </summary>
|
||
public override void stop()
|
||
{
|
||
if (!IsInit) return;
|
||
|
||
try
|
||
{
|
||
// 停止图像采集。
|
||
var ret = IKapBoard.IKapStopGrab(m_hBoard);
|
||
CheckIKapBoard(ret);
|
||
}
|
||
catch
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// num 因拍了一张后回传的,当前已经是1了
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
public override void resetScanIndex()
|
||
{
|
||
scanIndex = 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;
|
||
|
||
bool change = false;
|
||
//CParam cDeviceParam = new CParam(m_cInterface);
|
||
//int nRet;
|
||
//if (exposureTime != ExposureTime && exposureTime != -1)
|
||
//{
|
||
// nRet = cDeviceParam.SetEnumValue("ExposureAuto", (uint)0);
|
||
// if (CErrorCode.MV_FG_SUCCESS != nRet)
|
||
// WarningEvent?.Invoke(WarningEnum.Low, "ExposureTime SetEnumValue(\"ExposureAuto\") res=" + nRet);
|
||
// nRet = cDeviceParam.SetFloatValue("ExposureTime", exposureTime);
|
||
// if (CErrorCode.MV_FG_SUCCESS != nRet)
|
||
// WarningEvent?.Invoke(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();
|
||
}
|
||
|
||
//---------------
|
||
|
||
/* @brief:设置行触发参数。
|
||
*
|
||
* @brief:Set line trigger parameters. */
|
||
void SetLineTrigger()
|
||
{
|
||
int ret = (int)ErrorCode.IK_RTN_OK;
|
||
|
||
// 设置CC1信号源。
|
||
//
|
||
// Set CC1 signal source.
|
||
ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_CC1_SOURCE, (int)CCSource.IKP_CC_SOURCE_VAL_INTEGRATION_SIGNAL1);
|
||
CheckIKapBoard(ret);
|
||
|
||
// 设置积分控制方法触发信号源。
|
||
//
|
||
// Set integration control method trigger source.
|
||
ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_INTEGRATION_TRIGGER_SOURCE, (int)IntegrationTriggerSource.IKP_INTEGRATION_TRIGGER_SOURCE_VAL_SHAFT_ENCODER1);
|
||
CheckIKapBoard(ret);
|
||
}
|
||
|
||
/* @brief:清除回调函数。
|
||
*
|
||
* @brief:Unregister callback functions. */
|
||
private void UnRegisterCallback()
|
||
{
|
||
int ret = (int)ErrorCode.IK_RTN_OK;
|
||
|
||
ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStart);
|
||
ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameReady);
|
||
ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameLost);
|
||
ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_TimeOut);
|
||
ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStop);
|
||
}
|
||
|
||
/* @brief:关闭设备。
|
||
*
|
||
* @brief:Close device. */
|
||
private void CloseDevice()
|
||
{
|
||
// 关闭采集卡设备。
|
||
//
|
||
// Close frame grabber device.
|
||
if (!m_hBoard.Equals(-1))
|
||
{
|
||
IKapBoard.IKapClose(m_hBoard);
|
||
m_hBoard = (IntPtr)(-1);
|
||
}
|
||
}
|
||
|
||
/* @brief:判断 IKapBoard 函数是否成功调用。
|
||
* @param[in] ret:函数返回值。
|
||
*
|
||
* @brief:Determine whether the IKapBoard function is called successfully.
|
||
* @param[in] ret:Function return value. */
|
||
static void CheckIKapBoard(int ret)
|
||
{
|
||
if (ret != (int)ErrorCode.IK_RTN_OK)
|
||
{
|
||
string sErrMsg = "";
|
||
IKapBoard.IKAPERRORINFO tIKei = new IKapBoardClassLibrary.IKapBoard.IKAPERRORINFO();
|
||
|
||
// 获取错误码信息。
|
||
IKapBoard.IKapGetLastError(ref tIKei, true);
|
||
|
||
// 打印错误信息。
|
||
sErrMsg = string.Concat("Error",
|
||
sErrMsg,
|
||
"Board Type\t = 0x", tIKei.uBoardType.ToString("X4"), "\n",
|
||
"Board Index\t = 0x", tIKei.uBoardIndex.ToString("X4"), "\n",
|
||
"Error Code\t = 0x", tIKei.uErrorCode.ToString("X4"), "\n"
|
||
);
|
||
throw new Exception(sErrMsg);
|
||
}
|
||
}
|
||
|
||
#region Callback
|
||
delegate void IKapCallBackProc(IntPtr pParam);
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当图像采集开始时,函数被调用。
|
||
*
|
||
* @brief:This function is registered as a callback function. When starting grabbing images, the function will be called. */
|
||
private IKapCallBackProc OnGrabStartProc;
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当采集丢帧时,函数被调用。
|
||
*
|
||
* @brief:This function is registered as a callback function. When grabbing frame lost, the function will be called. */
|
||
private IKapCallBackProc OnFrameLostProc;
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当图像采集超时时,函数被调用。
|
||
*
|
||
* @brief:This function is registered as a callback function. When grabbing images time out, the function will be called. */
|
||
private IKapCallBackProc OnTimeoutProc;
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当一帧图像采集完成时,函数被调用。
|
||
*
|
||
* @brief:This function is registered as a callback function. When a frame of image grabbing ready, the function will be called. */
|
||
private IKapCallBackProc OnFrameReadyProc;
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当图像采集停止时,函数被调用。
|
||
*
|
||
* @brief:This function is registered as a callback function. When stopping grabbing images, the function will be called. */
|
||
private IKapCallBackProc OnGrabStopProc;
|
||
#endregion
|
||
|
||
#region Callback
|
||
/* @brief:本函数被注册为一个回调函数。当图像采集开始时,函数被调用。
|
||
* @param[in] pParam:输入参数。
|
||
*
|
||
* @brief:This function is registered as a callback function. When starting grabbing images, the function will be called.
|
||
* @param[in] pParam:Input parameter. */
|
||
public void OnGrabStartFunc(IntPtr pParam)
|
||
{
|
||
Console.WriteLine("Start grabbing image");
|
||
}
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当采集丢帧时,函数被调用。
|
||
* @param[in] pParam:输入参数。
|
||
*
|
||
* @brief:This function is registered as a callback function. When grabbing frame lost, the function will be called.
|
||
* @param[in] pParam:Input parameter. */
|
||
public void OnFrameLostFunc(IntPtr pParam)
|
||
{
|
||
Console.WriteLine("Image frame lost");
|
||
}
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当图像采集超时时,函数被调用。
|
||
* @param[in] pParam:输入参数。
|
||
*
|
||
* @brief:This function is registered as a callback function. When grabbing images time out, the function will be called.
|
||
* @param[in] pParam:Input parameter. */
|
||
public void OnTimeoutFunc(IntPtr pParam)
|
||
{
|
||
Console.WriteLine("Grab image timeout");
|
||
}
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当一帧图像采集完成时,函数被调用。
|
||
* @param[in] pParam:输入参数。
|
||
*
|
||
* @brief:This function is registered as a callback function. When a frame of image grabbing ready, the function will be called.
|
||
* @param[in] pParam:Input parameter. */
|
||
public void OnFrameReadyFunc(IntPtr pParam)
|
||
{
|
||
Console.WriteLine("Grab frame ready");
|
||
|
||
IntPtr hDev = (IntPtr)pParam;
|
||
IntPtr pUserBuffer = IntPtr.Zero;
|
||
int nFrameSize = 0;
|
||
int nFrameCount = 0;
|
||
IKapBoard.IKAPBUFFERSTATUS status = new IKapBoard.IKAPBUFFERSTATUS();
|
||
|
||
IKapBoard.IKapGetInfo(hDev, (uint)INFO_ID.IKP_FRAME_COUNT, ref nFrameCount);
|
||
IKapBoard.IKapGetBufferStatus(hDev, m_nCurFrameIndex, ref status);
|
||
|
||
// 当图像缓冲区满时。
|
||
//
|
||
// When the buffer is full.
|
||
if (status.uFull == 1)
|
||
{
|
||
// 获取一帧图像的大小。
|
||
//
|
||
// Get the size of a frame of image.
|
||
IKapBoard.IKapGetInfo(hDev, (uint)INFO_ID.IKP_FRAME_SIZE, ref nFrameSize);
|
||
|
||
// 获取缓冲区地址。
|
||
//
|
||
// Get the buffer address.
|
||
IKapBoard.IKapGetBufferAddress(hDev, m_nCurFrameIndex, ref pUserBuffer);
|
||
|
||
// === 保存图像。
|
||
//存文件
|
||
//IKapBoard.IKapSaveBuffer(hDev, m_nCurFrameIndex, m_strFileName, (int)ImageCompressionFalg.IKP_DEFAULT_COMPRESSION);
|
||
// 存到byte[]
|
||
byte[] imageBuff = new byte[nFrameSize]; // 创建字节数组
|
||
Marshal.Copy(pUserBuffer, imageBuff, 0, imageBuff.Length); // 将目标内存空间中的数据复制到结果字节数组
|
||
//存到地址
|
||
//IntPtr m_pDataBuf = Marshal.AllocHGlobal(nFrameSize); //分配空间
|
||
//CopyMemory(m_pDataBuf, pUserBuffer, (uint)nFrameSize);
|
||
//pictureBox1显示
|
||
if (this.previewHwnd != null && IsWindow(this.previewHwnd.Handle))
|
||
{
|
||
this.previewHwnd.Image = bytes2bmp(imageBuff);
|
||
}
|
||
|
||
}
|
||
m_nCurFrameIndex++;
|
||
m_nCurFrameIndex = m_nCurFrameIndex % m_nTotalFrameCount;
|
||
}
|
||
|
||
/* @brief:本函数被注册为一个回调函数。当图像采集停止时,函数被调用。
|
||
* @param[in] pParam:输入参数。
|
||
*
|
||
* @brief:This function is registered as a callback function. When stopping grabbing images, the function will be called.
|
||
* @param[in] pParam:Input parameter. */
|
||
public void OnGrabStopFunc(IntPtr pParam)
|
||
{
|
||
Console.WriteLine("Stop grabbing image");
|
||
}
|
||
#endregion
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|