将C缓冲区转换为C#位图对象

3
我有一个包含视频帧的BGR像素数据的缓冲区(uint8[]),在C中保存。指向此缓冲区的指针作为IntPtr由C代码传回给C#代码。我需要向每个帧添加文本叠加层,然后将指向该帧的指针传递给进一步处理。我认为我需要做的事情(在C#中)是将每个帧复制到位图对象中,获取位图的设备上下文,然后使用TextOut(等)将文本写入位图。然后,我将修改过的位图帧数据复制回原始数组。
我的问题有两个:
1.这是最好的方法吗? 2.从我的IntPtr复制数据到位图对象的最佳(最快)方法是什么?
谢谢。

我宁愿在C++/CLI中创建一个类,并在我的C#代码中使用它,而不是玩弄DllImports!如果你感兴趣,可以查看这个链接:https://dev59.com/NXE95IYBdhLWcg3wp_yn - MetallicPriest
2个回答

2
我不能评论你的方法,但使用两个指针复制数据的最快方法是通过对msvcrt.dll中的memcpy函数进行平台调用。
以下是代码示例,取自WriteableBitmapEx源代码
internal static class NativeMethods
{
    internal static unsafe void CopyUnmanagedMemory(byte* srcPtr, int srcOffset, 
                                        byte* dstPtr, int dstOffset, int count)
    {
        srcPtr += srcOffset;
        dstPtr += dstOffset;

        memcpy(dstPtr, srcPtr, count);
    }

    // Win32 memory copy function
    [DllImport("msvcrt.dll", EntryPoint = "memcpy", 
          CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
    private static extern unsafe byte* memcpy(byte* dst, byte* src, int count);
}

要将IntPtr转换为byte*,只需使用:
unsafe 
{
    IntPtr myPtr;
    byte* bytePtr = (byte*)myPtr.ToPointer();
}

使用C++/CLI作为粘合剂不是更好吗?虽然我已经很久没有在.net上工作了,但我记得曾经用C++/CLI创建一个类,然后直接在C#中使用它,而不是玩弄丑陋的dllimports。我认为这是一种更简单的方法。 - MetallicPriest
是的,你也可以这样做 - 这取决于你是否能够访问C源代码以插入C++/CLI,或者需要创建另一个DLL。如果你只需要执行memcpy操作,我会说C++/CLI有点过度了。然而,对于更复杂的互操作性问题,它非常有用。 - Dr. Andrew Burnett-Thompson
使用另一种解决方案,但我会记住这个以备将来参考。谢谢。 - integra753
@integra753 没问题,这是一个更好的解决方案 ;) - Dr. Andrew Burnett-Thompson

2

嗨,使用这个东西还不错。我的格式是24bpp,但是typedef显示我的源代码实际上是RGB(而不是代码中的枚举所说的BGR!)。谢谢。 - integra753

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接