views:

403

answers:

3

Here's a quick and easy question: using GDI+ from C++, how would I load an image from pixel data in memory?

A: 

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.

AJ
Sorry, I was being unclear. These are raw pixels. No image format.
Martin
Ah, in that case this wouldn't work, then.
AJ
A: 

This article describes how you can load a GDI+ image from a resource (rc) file. Loading the image from memory should be similar.

StackedCrooked
+2  A: 

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:

  1. Call GlobalAlloc() with the size of the BITMAPFILEHEADER, the BITMAPINFO, and your pixel data.
  2. In order, copy the BITMAPFILEHEADER, BITMAPINFO, and pixel data into the new memory (call GlobalLock to get the new memory pointer).
  3. 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!

gdunbar
Ugh, you're right; that is far more complex than I would have ever imagined. I hope I can get it working.
Martin
Good luck! The BITMAPINFO stuff is fussy; looking at a 24-bit BMP file in a hex-editor can be helpful, to compare what you're doing with the real thing. (Visual Studio can do this; open the file, but use the "Open With" option, and pick "Binary Editor").
gdunbar