C# · 12月 20, 2021

使用Emgucv 读取bmp图片,将图片数据传入 C++dll中,并得到处理过的图片数据

使用C#来做界面以及图片的反复读取,为了利用C#的回收机制,不必担心内存泄漏问题

Image image = null;

Image outframe;

Bitmap bitmap;

MIplImage mlI;

foreach (var strImg in m_ImgList)

{

string strImgName = “图片路径/” + strImg ;

bitmap = new Bitmap(strImgName);

image = new Image(bitmap);

IntPtr ptrImg = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(image),

                    Emgu.CV.CvEnum.IplDepth.IplDepth_8U,image.Mat.NumberOfChannels);

CSharpAlg.ImgAlg(m_AlgPtr,image.Ptr,ptrImg);

//dll 接口定义: public static extern int ImgAlg(IntPtr pHandle,IntPtr pSrcImg,IntPtr pIplImg);

mlI = (MIplImage)Marshal.PtrToStructure(ptrImg,typeof(MIplImage));//托管与非托管的转换 

outframe =  new Image(mlI.Width,mlI.Height,mlI.WidthStep,mlI.ImageData);

// 在后台线程中进行C++ dll函数调用,使用代理进行界面图片显示

this.Invoke(new Action(() =>

{

    pbPicShow.Image = outframe.ToBitmap(); 

 }));

// 完成后进行内存释放;在后台线程执行完之前,不会进行回收,图片过多时会导致内存用完,new失败

CvInvoke.cvReleaseImage(ref ptrImg);

bitmap.Dispose();

image.Dispose();

}

// C++ dll的接口代码

ALG_DLL_EXP int __cdecl ImgAlg(ALG_HANDLE pHandle,IplImage* pSrc,

    IplImage* pImg)

{

int nRet = -1;

AlgClass* pAlg = (AlgClass*)pHandle;

*pImg = *pSrc;

cv::Mat imgMat(pImg);

nRet  = pAlg ->ImgAlg(imgMat);

*pImg = imgMat;

return nRet;

}