Initially I thought to send an image from C++ opencv to C# required converting the opencv mat to an equivalent emgucv object. I have come to learn that it just requires unpacking the mat object to a type that C# can understand, which is uchar . . .apparently same as byte in C#
I have a C++ program that reads and an image and converts it to uchar (which is what a Mat object is anyway).
void DisplayImage::ReadImage()
{
cv::Mat image = cv::imread("2015-02-05.jpg");
image_rows = image.rows;
image_cols = image.cols;
image_type = image.type();
//image_uchar is data member of uchar*
image_uchar = MatToBytes(image);
}
uchar *DisplayImage::MatToBytes(cv::Mat image)
{
int image_size = image.total() * image.elemSize();
uchar * image_uchar = new uchar[image_size];
//image_uchar is a class data member of uchar*
std::memcpy(image_uchar,image.data,image_size * sizeof(uchar));
return image_uchar;
}
cv::Mat DisplayImage::BytesToMat()
{
cv::Mat img(image_rows,image_cols,image_type,image_uchar,cv::Mat::AUTO_STEP);
return img;
}
In the main program I assign a Mat object to the returned value from BytesToMat() and image looks fine.
My DLL looks like below
DisplayImage displayImage = DisplayImage();
extern "C" __declspec(dllexport) void SetImage()
{
displayImage.ReadImage();
}
extern "C" __declspec(dllexport) uchar *GetImage()
{
return displayImage.image_uchar;
}
Just by the way; I firstly started by assigning the pointer to uchar (in C++) with a simple text and displayed it C# by Marshaling returned IntPtr (from dll) to PtrToStringAnsi and it worked.
[DllImport(@".\WrapperForPlayer.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
unsafe public static extern IntPtr GetImage();
[DllImport(@".\WrapperForPlayer.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void SetImage();
static void Main(string[] args)
{
//byte[] image_byte = new byte[500];
SetImage();
IntPtr intPtr = GetImage();
unsafe
{
byte* image_byte = (byte*)intPtr;
}
Console.Read();
}
The only difference now is that the returned IntPtr contains address to image data which I want to turn to byte[] and then it will be easy to convert to Bitmap. How can I do that?