Búfer de C a objeto de mapa de bits de C #

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.

Mi pregunta es doble:

  1. ¿Es este el mejor enfoque?
  2. What is the best (fastest) way to copy the data from my IntPtr to a bitmap object.

Gracias.

preguntado el 02 de febrero de 12 a las 10:02

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/… -

2 Respuestas

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

Respondido 02 Feb 12, 15:02

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

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

Respondido 02 Feb 12, 15:02

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. - Sacerdote Metálico

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

Using the other solution but, I'll remember this for future reference. Thanks. - integra753

@integra753 no problem, it was a better solution ;) - Dr. Andrew Burnett-Thompson

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.