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# 位图对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 pinvoke 将二进制数据缓冲区从 C 传递到 C#