Loading an image from memory, GDI+
Question
Here's a quick and easy question: using GDI+ from C++, how would I load an image from pixel data in memory?
Solution
Probably not as easy as you were hoping, but you can make a BMP file in-memory with your pixel data:
If necessary, translate your pixel data into BITMAP-friendly format. If you already have, say, 24-bit RGB pixel data, it is likely that no translation is needed.
Create (in memory) a BITMAPFILEHEADER structure, followed by a BITMAPINFO structure.
Now you've got the stuff you need, you need to put it into an IStream so GDI+ can understand it. Probably the easiest (though not most performant) way to do this is to:
- Call GlobalAlloc() with the size of the BITMAPFILEHEADER, the BITMAPINFO, and your pixel data.
- In order, copy the BITMAPFILEHEADER, BITMAPINFO, and pixel data into the new memory (call GlobalLock to get the new memory pointer).
- Call CreateStreamOnHGlobal() to get an IStream for your in-memory BMP.
Now, call the GDI+ Image::FromStream() method to load your image into GDI+.
Good luck!
OTHER TIPS
There's a bitmap constructor which takes a BITMAPINFO and a pointer to pixel data directly, for example:
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = 32;
bmi.bmiHeader.biHeight = 32;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 24;
char data[32 * 32 * 3];
// Write pixels to 'data' however you want...
Gdiplus::Bitmap* myImage = new Gdiplus::Bitmap(&bmi, data);
That's OK for an RGB image, if it's a palette image you'd need to allocate a BITMAPINFO with enough space for the RGBQUADS etc etc.
Use SHCreateMemStream, it takes a pointer to the data and the size of the data.
IStream *pStream = SHCreateMemStream((BYTE *) InputBuffer, Size);
// Do what you want
pStream->Release();
Is the "pixel data in memory" formatted as a particular image type, i.e., bitmap, TIF, PNG, etc.? If so, get it into a stream and use System.Drawing.Image.FromStream.
This article describes how you can load a GDI+ image from a resource (rc) file. Loading the image from memory should be similar.