从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!!!