我在使用第三方的图像采集代码库(C++编码),想转成C#,结果不知如何实现?
我尽可能提供更加详细的信息,期待大神能够帮忙解决。
1)第三方提供的图像采集头文件:--------------------------------------
#ifndef ATCAM_H
#define ATCAM_H
#ifdef ATCAM_EXPORTS
#define ATCAM_API __declspec(dllexport)
#else
#define ATCAM_API __declspec(dllimport)
#endif
//Parameters Defines
#define PARA_CAM_INT 0x5001
#define PARA_CAM_GAIN 0x5002
//Acquire Information
typedef struct _AtInfo
{
int CodeAcq; //Code Acquire
void * pData; //Data Pointer
void * Context; //Context For User Application
}AtInfo,*PAtInfo;
//CallBack Function
typedef void (__stdcall *AtCallBack)(AtInfo * pInfo);
#ifdef __cplusplus
extern "C" {
#endif
//Get Device Count
ATCAM_API int __stdcall AtCamDev( int * count );
//Open the Selected Device
ATCAM_API int __stdcall AtCamOpen( int devNo );
//Close the Selected Device
ATCAM_API int __stdcall AtCamClose( int devNo );
//Get Device Parameters
ATCAM_API int __stdcall AtCamGet( int devNo, int para, void * buf );
//Set Device Parameters
ATCAM_API int __stdcall AtCamSet( int devNo, int para, int * buf );
//Start Acquire
ATCAM_API int __stdcall AtCamStart( int devNo, PAtInfo pInfo, AtCallBack callBack );
//Stop Acquire
ATCAM_API int __stdcall AtCamStop( int devNo );
#ifdef __cplusplus
}
#endif
#endif
2)C++中图像采集实现:----------------------------------------------
头文件中的定义:
AtInfo m_sInfo;
static void __stdcall AcqCallBack(PAtInfo pInfo);
在*.cpp文件中
AtCamStart(0,&m_sInfo,AcqCallBack);
//采集回调函数
void CAtCamDemoDlg::AcqCallBack(PAtInfo pInfo)
{
//获取上下文信息,发送更新消息
CAtCamDemoDlg * pDlg = (CAtCamDemoDlg*)pInfo->Context;
::PostMessageW( pDlg->m_hWnd,WM_ACQUIRED,(WPARAM)pInfo,pInfo->CodeAcq );
}
/采集更新消息函数
LONG CAtCamDemoDlg::OnAcquired(WPARAM wParam, LPARAM lParam)
{
//未启动采集,返回
if( false == m_bAcquiring )
return 0;
//采集结果判断
int rc = (int)lParam;
if( 0!=rc )
{
OnBnClickedBtnRun();
MessageBox(_T("采集失败!"),_T("错误"),MB_OK);
}
else
{
//成功采集,拷贝数据,更新显示
memcpy(m_pDataBuf, m_sInfo.pData, IMAGES);
if( false == m_ctrlImage.m_bUpdating )
m_ctrlImage.UpdateImage(m_pDataBuf);
}
return 0;
}
3)我在C#中的定义:----------------------------------------------------
public struct AtInfo
{
public int CodeAcq;
public IntPtr pData;
public IntPtr Context;
};
//grab start
[DllImport("AtCam.dll", EntryPoint = "AtCamStart")]
public static extern int AtCamStart(int devNo, out AtInfo pInfo, AtCallback callback);
4)我的实现:----------------------------------------------------------
开始采集
private void Btn_GrabStart_Click(object sender, EventArgs e)
{
if (!camOpened) return;
if (inAcquiring) return;
int ret = 0;
ret=OptiMat.AtCamStart(0, out sInfo, AcqCallback);
textBox1.Text += Environment.NewLine + "Capture Start return: " + ret.ToString();
inAcquiring = true;
}
回调:
private void AcqCallback(out AtInfo info)
{
AtInfo info0 = new AtInfo();
info=info0;
OptiMatImage.PostMessage(hShowMsgWin, OptiMatImage.IMG_MESSAGE, info.CodeAcq, info);
}
消息处理:
protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
//接收自定义消息MYMESSAGE,并显示其参数
case OptiMatImage.IMG_MESSAGE:
AtInfo ml = new AtInfo();
ml.pData = m.LParam;
ml.CodeAcq = (m.WParam).ToInt32();
ShowImage(ml);
break;
default:
base.DefWndProc(ref m);
break;
}
}
图像显示:
private void ShowImage(AtInfo ip)
{
Marshal.Copy(ip.pData, dataBuf, 0, OptiMat.IMAGES);
}
在这一步会出现以下错误:
请指出------------------------------------------------------------------
1)哪里出现错误了;
2)我不熟悉这种转换,如何改进比较好?
我们公司是做相机的,是提供了一套接口来采集图片数据,我给客户开发过c#程序,先简单在这里写一下吧:
byte[] pImageData = new byte[nCaptureWidth * nCaptureHeight * (nCaptureBitCount >> 3)];
KSJApiBase.KSJ_CaptureRgbData(m_nDeviceCurSel, pImageData);
而接口我在调用时候重新进行了声明:
extern int KSJ_CaptureRgbData(int nChannel, byte[] pRgbData);
我不知道你那边是什么问题,不过你可以参考一下,其实就是把byte*变成了 byte[],之后的其他处理,就是c#内部的问题了。
你可以将C++的代码封装成dll,然后用C#去调用,如果需要帮助请留言
@lengyue2015,需要帮助,我这边要提供啥?
将C++ IplImage 图像用C#读取 需要安装emgucv ,也可以自己实现这个类
https://www.cnblogs.com/hust-yingjie/p/5504748.html