从C#传递位图的C ++
我有一个图像处理功能用C ++编写基于OpenCV。在我的WPF应用程序我已经使用AForge库访问一个摄像头和更新的用户界面。这个处理newframes功能。
I have an image processing function written in C++ based on opencv. In my wpf application I have used AForge library to access a webcam and update it on UI. This the function for handling newframes.
void UI_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
System.Drawing.Bitmap bitmapFrame = (Bitmap)eventArgs.Frame.Clone();
MemoryStream ms = new MemoryStream();
bitmapFrame.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
BitmapImage bitmapImageFrame = new BitmapImage();
bitmapImageFrame.BeginInit();
bitmapImageFrame.StreamSource = ms;
bitmapImageFrame.EndInit();
bitmapImageFrame.Freeze();
CurrentFrame = bitmapImageFrame;
}
catch (Exception ex)
{
Debug.WriteLine("fatal::" + ex.Message);
}
}
这是我的C ++ code:
This my c++ code:
void FaceTracker(unsigned char* imageBuffer, int width, int height){
Mat frame(Size(width, height), CV_8UC4, imageBuffer, Mat::AUTO_STEP);
Mat gray;
cvtColor(frame, gray, COLOR_BGR2GRAY);
//do more operations
}
我有两个选择。我已经找到了一个code使用从的BitmapImage
将数据复制到的IntPtr
缓冲 CopyPixels
。我测试了它,它工作正常。但我也看了,我可以使用 GetHBitmap
简单地传递一个句柄位图。然而,这不是为我工作。我读这How我可以通过一个.NET位图到本机DLL?,但我不明白关于的GetDIBits
部分。我也试过锁定位图的像素,并通过这样的:
I have two options. I have already found a code for copying data from BitmapImage
to a IntPtr
buffer using CopyPixels
. I tested it and it works fine. But I also read I can simply pass a handle to the Bitmap using GetHBitmap
. However this is not working for me. I read this How can I pass a .NET Bitmap to a native DLL? but I don't understand the part about GetDIBits
. I also tried locking pixels of bitmap and passing like this:
bitmapFrame.LockBits(new Rectangle(0, 0, bitmapFrame.Width, bitmapFrame.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
NativeFunctions.FaceTracker(bitmapFrame.GetHbitmap(), bitmapFrame.Width, bitmapFrame.Height);
和只是传递HBITMAP,无论是作品。我总是得到一个异常,说明内存访问冲突。
and simply passing HBitMap, neither works. I always get an exception stating memory access violation.
取决于范围。如果你能保证位图没有被其它地方使用,可以锁定图像缓冲区,然后传递指针下降到C ++ code,事后解锁。
Depends on the scope. If you can guarantee the bitmap isn't used elsewhere, you can lock the image buffer, and then pass the pointer down to the C++ code, and unlock it afterwards.
在 LockBits 命令返回的的的BitmapData A> 类,它具有一个指向图像缓冲区在其 SCAN0 属性:
The LockBits command returns a BitmapData class that has a pointer to the image buffer in its Scan0 property:
BitmapData bmpData = bitmapFrame.LockBits(new Rectangle(0, 0, bitmapFrame.Width, bitmapFrame.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
ativeFunctions.FaceTracker(bmpData.Scan0 , bitmapFrame.Width, bitmapFrame.Height);
bitmapFrame.UnlockBits(bmpData); //Remember to unlock!!!