roma roma - 14 days ago 10
C# Question

pass mat from dll c++ to imagesource c#

I'm working with Visual C# 2010, and I like to send an image from DLL C++ to my Visual C# 2010. The image has 166*166*24 to send the image from DLL C++ to C#. I'm using this code:

main.cpp

unsigned char* test()
{
read image from filename
Mat OriginalImg = imread(fileName, CV_LOAD_IMAGE_COLOR);
return (OriginalImg.data);}
OriginalImg.data return the pointer to the image.


main.h

extern "C" { __declspec(dllexport) unsigned char* test();}


and in my program Visual C#, I use this code:

[DllImport("testng.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr test();

IntPtr intPtr1;

BitmapImage bitmapImage;
calling the c++ dll
intPtr1 = test(1);

if (intPtr1.ToString().CompareTo("0") != 0)
{
create a bitmap with the pointer
Bitmap bitmap = new Bitmap(166, 166, 3 * 166, System.Drawing.Imaging.PixelFormat.Format24bppRgb, intPtr1);
to show the bitmap i need to convert it to a bitmap image
bitmapImage=convertBitmapToBitmapImage(bitmap);
System.Windows.Media.ImageBrush ib = new System.Windows.Media.ImageBrush();
ib.ImageSource = bitmapImage;
i put the image received from c++ dll like a background to my canvas: canvasImage
windows.canvasImage.Background = ib;
}

BitmapImage convertBitmapToBitmapImage(Bitmap bitmap)
{

IntPtr hBitmap = bitmap.GetHbitmap();

BitmapSource retval;

try
{
retval = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
finally
{
//DeleteObject(hBitmap);

}

return (BitmapImage)retval;



}

Answer

My guess is the pointer to the cv::Mat data is no longer valid after function test() returns, because variable OriginalImg gets out of scope, destructors have cleaned OriginalImg data. Try making OriginalImg global if it is possible to prevent automatic destroy of the variable.

In general, I recommend making a generic C++/CLI wrapper for OpenCV. A made a post about that. For example, I'm working now on the same problem as you and I'm creating a System.Drawing.Bitmap object in C++/CLI without any DllImports...