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.

1
  • 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 stackoverflow.com/questions/2211867/… Commented Feb 2, 2012 at 11:05

2 Answers 2

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).

Sign up to request clarification or add additional context in comments.

1 Comment

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.
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();
}

4 Comments

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.
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
Using the other solution but, I'll remember this for future reference. Thanks.
@integra753 no problem, it was a better solution ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.