I will be receiving some raw data that will be stored in a byte array, where each 2 bytes is a pixel value (16 bits/px). To start with, the array will contain 100x100*2 bytes (enough for a 100x100 pixel image). I would like to display this data in the Form window. Eventually, I would like to refresh the image with the new data to make it look like a video stream. No strict frame rate is required. How can this be done? Any code examples in C#?
EDIT: After some suggestions and reviews of tens of similar questions I still can not get this going. Here's the general idea of what I am trying to do, but the image is not displayed in the picture box on the form. What is specifically wrong with my implementation and how to fix it?
// array of data I collected
byte[] dataArray = new byte[100 * 100 * 2];
//create a pointer to the data
IntPtr hglobal = Marshal.AllocHGlobal(100 * 100 * 2);
// copy my array to global
Marshal.Copy(dataArray, 0, hglobal, dataArray.Length);
// create a bitmap: 100x100 pixels, 2bytes/pixel, 16bitgrayscale
Bitmap newBitmap = new Bitmap(100, 100, 2 * 100, PixelFormat.Format16bppGrayScale, hglobal);
// display bitmap
pictureBox1.Image = newBitmap;
// free the memory
Marshal.FreeHGlobal(hglobal);
Use this
Bitmap
constructor:You pass it the shape of your bitmap, the stride (how many bytes per line, including padding), pixel format and the pixel data as a
void *
pointer. You can create the latter withMarshal.AllocHGlobal
and fill it in as normal with pointer operations. Don't forget to free this memory after you create your bitmap.Edit to account for updated question:
Simply call
IntPtr.ToPointer()
to get back a pointer. If you're familiar with C, the rest should be cake:However, you can use the Marshaller to copy memory for you from managed to unmanaged (getting your hands dirty is usually frowned upon in C#):
A
Bitmap
is anImage
(as in, it derives from it), however you're usingGraphics.DrawImage()
wrong. As the error says, it's not a static method, you draw it to a specific graphic context. Now what that graphic context is, that's up to you:WM_PAINT
, use thePaint
event -- it provides you with a specialGraphics
object set up with clipping and everything as instructed by the windowing system.Graphics.FromImage()
on the source bitmap then draw your bitmap over it.You can (and should) delete your virtual memory buffer as soon as you get the result back from the
Bitmap
constructor. Don't leak memory, use atry..finally
construct.The main problem is that PixelFormat.Format16bppGrayScale is not supported (at least on my Win 8.1 x64 system). So you have to convert image to rgb before displaying:
Idea was taken from this thread.