如何从C#传递管理位图裹非托管的OpenCV的垫 [英] How to pass managed Bitmap from C# to wrapped unmanaged OpenCV's Mat

查看:176
本文介绍了如何从C#传递管理位图裹非托管的OpenCV的垫的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个部分项目:


  1. 有一个回调,给了我一个位图托管C#项目(它应该具有的PixelFormat = Format24bppRgb)。我试过几种方法的位图到的东西我能传递给第2部分转换,这是我试过的最后一件事:

  1. Managed C# project with a callback which gives me a Bitmap (it should have PixelFormat = Format24bppRgb). I've tried several ways to convert the Bitmap into something I could pass to part 2, that's the last thing I've tried:

public int BufferCB(IntPtr pBuffer, int BufferLen)
{
    byte[] aux = new byte[BufferLen];
    Marshal.Copy(pBuffer, aux, 0, BufferLen);
    String s_aux = System.Text.Encoding.Default.GetString(aux);
    wrappedClassInstance.GetBitmap(s_aux);
}


  • 托管C ++ / CLI包装项目3:

  • Managed C++/CLI to wrap item 3:

    int WrappedClass::GetBitmap(array<System::Byte>^ s_in) {
        pin_ptr<unsigned char> pin = &s_in[0];
        unsigned char* p = pin;
        return privateImplementation->GetBitmap(p);
    }
    


  • 非托管C,它使用了OpenCV ++应用程序。我想这个数据加载到凉席:

  • Unmanaged C++ application that uses OpenCV. I want to load this data into a Mat with:

    Mat myMat;
    int NativeClass::GetBitmap(unsigned char *s_in) {
    
        // If there's no input:
        if (!s_in) {
            return -1;
        }
        /* h and w are defined elsewhere */
        myMat = Mat(h, w, CV_8UC3, (void *)s_in, Mat::AUTO_STEP));
        imwrite("test.bmp", myMat);
        return 0;
    }
    


  • 当达到一个异常的imwrite功能被抛出:System.Runtime.InteropServices.SEHException(0X80004005)。它没有说太多,但我猜当我整理它,我传递到垫中的数据被损坏了。

    When the the imwrite function is reached an exception is thrown: "System.Runtime.InteropServices.SEHException (0x80004005)". It doesn't say much, but I'm guessing the data I passed into the Mat got corrupted when I've marshalled it.

    之前,我是想传递数据,而无需一个包装:

    Before, I was trying to pass the data without a wrapper:

    [DllImport("mydll.dll", ...)]
    static extern void GetBitmap(IntPtr pBuffer, int h, int w);
    
    void TestMethod(IntPtr pBuffer, int BufferLen)
    {
        // h and w defined elsewhere
        // GetBitmap is essentially the same as in item 3.
        GetBitmap(pBuffer, BufferLen, h, w);
    }
    

    和起作用的(它保存了位图到文件),但因为DLL保持连接直到我杀的过程,解决方案是不是对我不够好。我也不想镜子的垫类到我的项目,因为我知道应该垫一些字符接收数据*。

    and that worked (it saved the Bitmap into the file), but because the DLL stays attached until I kill the process that solution is not good enough for me. I also don't want to "mirror" the Mat class into my project, as I know Mat should accept data from some char*.

    请帮帮忙,我该怎么办呢?我做错了类型转换?

    Please help, how can I do this? Am I doing wrong type conversions?

    感谢您。

    推荐答案

    我已经改变了部分2到memcpy的非托管内存到本机内存,只是要确定。但随着我的code,真正的问题是,每次我想要得到一个新的垫子,我会打电话给垫的构造函数:

    I've changed part 2 to memcpy unmanaged memory into native memory, just to be sure. But the real problem with my code was that everytime I wanted to get a new Mat, I'd call Mat constructor:

    Mat myMat;
    int MyClass::GetBitmap(unsigned char* s_in) {
        myMat = Mat(...)
    }
    

    相反,我所做的:

    Instead, I did:

    Mat myMat;
    int MyClass::GetBitmap(unsigned char* s_in) {
        Mat aux;
        aux = Mat(...)
        aux.copyTo(myMat);
        aux.release();
    }
    

    ...现在我的code为正常使用。

    ... and now my code is working perfectly.

    编辑:
    删除,这使用了一些部件新垫(...),这是一个错字,它不会编译,因为我使用的垫子,不是太*。

    Removed some parts which used new Mat(...), it was a typo and it wouldn't compile because I'm using Mat, not Mat*.

    这篇关于如何从C#传递管理位图裹非托管的OpenCV的垫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆