C 缓冲区到 C# 位图对象

Posted

技术标签:

【中文标题】C 缓冲区到 C# 位图对象【英文标题】:C Buffer to C# Bitmap Object 【发布时间】:2012-02-02 10:54:12 【问题描述】:

我在 C 中有一个缓冲区(BGR 像素数据的 uint8[]),用于保存视频帧。 C 代码将指向此缓冲区的指针作为 IntPtr 传递回 C# 代码。我需要为每一帧添加一个文本覆盖,然后将指针传递给该帧以进行进一步处理。我相信我需要做的(在 C# 中)是将每一帧复制到一个位图对象,获取位图的设备上下文,然后使用 TextOut(等)将文本写入位图。然后我会将修改后的位图帧数据复制回我的原始数组。

我的问题有两个:

    这是最好的方法吗? 将数据从 IntPtr 复制到位图对象的最佳(最快)方法是什么。

谢谢。

【问题讨论】:

我宁愿在 C++/CLI 中创建一个类并在我的 C# 代码中使用它,而不是玩弄 DllImports!如果你有兴趣,请看这个***.com/questions/2211867/… 【参考方案1】:

最快的方法是不复制数据。这要求您的数据采用受支持的像素格式,BGR 听起来有点吓人,但几率很高,它实际上是 PixelFormat.Format24bppRgb。

然后允许您使用Bitmap(int, int, int, PixelFormat, IntPtr constructor)。

【讨论】:

您好,使用它并且工作正常。我的格式是 24bpp,而 typedef 原来我的源是 RGB(而不是像代码中的枚举所说的 BGR!)。谢谢。【参考方案2】:

我无法评论您的方法,但使用两个指针复制数据的最快方法是对 msvcrt.dll 中的 memcpy 函数进行 Platform Invoke 调用

以下代码示例,取自WriteableBitmapEx source

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。我会说一种更简单的方法。 是的,您也可以这样做 - 取决于您是否有权访问 C 源代码以在其中插入 C++/CLI,或者需要创建另一个 DLL。我想说,如果您只需要一个 memcpy,那么 C++/CLI 就太过分了。然而,它对于更复杂的互操作非常有用 使用其他解决方案,但我会记住这一点以供将来参考。谢谢。 @integra753 没问题,这是一个更好的解决方案;)

以上是关于C 缓冲区到 C# 位图对象的主要内容,如果未能解决你的问题,请参考以下文章

使用 libpng 将位图缓冲区快速编码为 png

用winsock发送位图

如何使用 pinvoke 将二进制数据缓冲区从 C 传递到 C#

从内存创建 Windows GDI 位图

WebGL - 发送数组缓冲区 VS 将图像/画布/位图从 CPU 发送到 GPU

反序列化协议缓冲区c ++中的字符串数组