3

I have a buffer (uint8[] of BGR pixel data) in C holding a video frame. A pointer to this buffer is passed back by the C code to C# code as an IntPtr. I require to add a text overlay to the each frame and then pass on a pointer to the frame for further processing. I believe what I need to do (in C#) is to copy each frame to a bitmap object, get the device context of the bitmap and use then use TextOut (etc) to write text to the bitmap. I would then copy the modified bitmap frame data back to my original array.

My question is twofold:

  1. Is this the best approach?
  2. What is the best (fastest) way to copy the data from my IntPtr to a bitmap object.

Thanks.

integra753
  • 271
  • 1
  • 5
  • 19
  • I would rather make a class in C++/CLI and use it in my C# code rather than playing around with DllImports! If you are interested, see this http://stackoverflow.com/questions/2211867/how-do-i-call-native-c-from-c – MetallicPriest Feb 02 '12 at 11:05

2 Answers2

2

I can't comment on your approach, but the fastest way to copy data using two pointers would be to do a Platform Invoke call to the memcpy function in msvcrt.dll

Code example below, taken from the 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);
}

To convert an IntPtr to byte* simply use

unsafe 
{
    IntPtr myPtr;
    byte* bytePtr = (byte*)myPtr.ToPointer();
}
Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
  • Isn't it better to use C++/CLI as a glue? Although its been a long time since I worked in .net, I remember once making a class in C++/CLI and then using it directly in C#, rather than playing around with ugly dllimports. A much easier approach I would say. – MetallicPriest Feb 02 '12 at 11:04
  • Yes you could do that also - depends if you have access to the C source code to insert C++/CLI there, or need to create another DLL. I'd say if all you need to do is a memcpy then C++/CLI is overkill. However its very useful for more complex interop – Dr. Andrew Burnett-Thompson Feb 02 '12 at 11:07
  • Using the other solution but, I'll remember this for future reference. Thanks. – integra753 Feb 02 '12 at 14:27
  • @integra753 no problem, it was a better solution ;) – Dr. Andrew Burnett-Thompson Feb 02 '12 at 18:41
2

The fastest way is by not copying the data. That requires that your data is in a supported pixel format, BGR sounds a bit scary but odds are high it is actually PixelFormat.Format24bppRgb.

Which then allows you to use the Bitmap(int, int, int, PixelFormat, IntPtr constructor).

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hi using this and its working OK. My format was 24bpp and the typedef it turned out my source was RGB (and not BGR like the enums in the code said!). Thanks. – integra753 Feb 02 '12 at 14:26