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

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

我的问题有两个:

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

谢谢。

【问题讨论】:

标签: c# c bitmap


【解决方案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 没问题,这是一个更好的解决方案;)
猜你喜欢
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 2013-01-17
  • 1970-01-01
相关资源
最近更新 更多