Since the latest version, GdiPlusX offers many different ways to manipulate images with no disk access.
This introduction is from Calvin Hsia, from his blog: "Programs need to read and write data. Sometimes the data storage is only used temporarily. If the storage medium is a file, temporary files need to be deleted. Some Windows APIs allow reading and writing data to an object that implements IStream. IStream has methods that read and write to the underlying storage, which can be a file, memory, or even a named pipe: whatever the object chooses. (...) Using memory for the stream instead of a disk file can be much faster, and releasing the stream can free the used memory."
Sometimes we need to do some manipulation in some images on the fly, and show them in a picture object. This image does not need to be saved. Since VFP9, with the PictureVal property, we can send just the binaries from our images to the PictureVal property. In other cases, users may need to save only the binaries in a table or cursor field, or even do some bit per bit or byte per byte manipulation in the image.
Think of a Memory Stream just like a disk stored in the memory. You can do with a memory stream the same things you do with a disk file: read and write. Instead of a physical location, it is stored in the memory. MSDN says: "The MemoryStream class creates streams that have memory as a backing store instead of a disk or a network connection. The encapsulated data is directly accessible in memory. Memory streams can reduce the need for temporary buffers and files in an application."
GDI+ brings functions that allow us to manipulate images using streams just like we do with phisical files. We can read a bitmap from the binaries retrieved from a stream and we can send all the binaries of the image in any desired format to a stream.
Last year, Calvin Hsia came with a great post, Use an IStream object to avoid disk access http://blogs.msdn.com/calvin_hsia/archive/2006/02/17/534529.aspx, when he created a simple COM wrapper that can read and write a stream. That DLL works great, and brings some important functions to manipulate streams with GDI+. The only problem is that it uses a COM object, that needs to be registered, using the REGSVR32 command. That article is highly recommended.
After a lot of discussion, researches and tests we finally managed to finish the GdiPlusX MemoryStream class, using only pure VFP code, with some API calls. The final magic that really enabled us to finish it came from the FoxPert Christof Wollenhaupt, in a UT thread. Thanks Christof !
The "MemoryStream" class is stored in the "System.IO" namespace.
The samples below show some ways to manipulate streams with GdiPlusX, and obtain the PictureVal binary string for an image loaded using GETPICT() function. In all samples, the PictureVal obtained will be stored in an imaginary Image object from your imaginary form. In some of the cases, all the job will be done "behind the scenes", allowing the user to do tasks without even knowing what a Memory Stream is.
In these samples we'll be loading an image using the GETPICT() command, and obtain the PictureVal using Memory Streams
Also, for didactic purposes, I'm putting the full codes needed, including the library initialization on every sample.
IMPORTANT
Requires VFP9 and GdiPlusX to run.
Please make sure that you have the latest version, because VFPPaint uses some functions that were added recently.
http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home

1 - BASIC USAGE
This aproach is totally compatible with the .NET classes
* Sample 1 - BASIC USAGE
*
* Load the image to GDI+
* Create an empty Stream
* Save the image to the Stream
* Retrieve the Image binaries from the stream and store in PictureVal Property
DO LOCFILE("System.Prg")
LOCAL loBmp as xfcBitmap
LOCAL loStream as xfcMemoryStream
loStream = _Screen.System.IO.MemoryStream.New()
* Saving to a stream and retrieving to PictureVal
WITH _Screen.System.Drawing
loBmp = .Bitmap.FromFile(GETPICT())
loBmp.Save(loStream, .Imaging.ImageFormat.Jpeg)
Thisform.Image1.PictureVal = loStream.GetBuffer()
ENDWITH
The samples below use some functions that were created or adapted only in GdiPlusX. Unfortunately, there's still not a documentation available for them, so I'll try to get you started:
2 - SAVING DIRECTLY TO IMAGE OBJECT
This is really cool. You can manipulate an image, draw on it, aply some special effects, rotate, flip, etc, and then send it directly to an image object in your form.
To do this, use the SAVE() method from the Bitmap / Image class, sending 3 parameters:
SAVE() additional parameters
toImage - VFP Image object
toEncoder - xfcImageFormat (eg. .Imaging.ImageFormat.Bmp)
toEncoderParams - xfcEncoderParameter (for the case of JPGs with specific quality)
Note that you can even choose in what image format the pictureval will be obtained !
* Sample 2 - Saving directly to Image object
*
* Load the image to GDI+
* Save the image to the VFP Image object
DO LOCFILE("System.Prg")
LOCAL loBmp as xfcBitmap
* Saving directly to Image object
WITH _Screen.System.Drawing
loBmp = .Bitmap.FromFile(GETPICT())
loBmp.Save(Thisform.Image1, .Imaging.ImageFormat.Jpeg)
ENDWITH
3 - GETPICTUREVAL() FUNCTION
Another cool way to get the PictureVal, is just calling the new GETPICTUREVAL() function
GETPICTUREVAL() Parameters:
toEncoder - xfcImageFormat (eg. .Imaging.ImageFormat.Bmp)
toEncoderParams - xfcEncoderParameter (for the case of JPGs with specific quality)
* Sample 3 - Using the GetPictureVal function
*
* Load the image to GDI+
* Call the Bitmap.GetPictureVal() function
DO LOCFILE("System.Prg")
LOCAL loBmp as xfcBitmap
* Obtaining the PictureVal directly
WITH _Screen.System.Drawing
loBmp = .Bitmap.FromFile(GETPICT())
Thisform.Image1.PictureVal = loBmp.GetPictureVal(.Imaging.ImageFormat.Bmp)
ENDWITH
4 - GETPICTUREVALFROMHBITMAP() FUNCTION
The result and usage of GETPICTUREVALFROMHBITMAP is very similar GETPICTUREVAL.
It retrieves the PictureVal binaries from the bitmap using ONLY the BMP ENCODER. Behind the scenes, these functions work totally different. This functions does not use the MemoryStream class that I referred in this post. In summary,it obtains the PictureVal for BMP doing the following steps internally: 1 - gets the hBitmap handle for the picture (the old GDI hande for pictures); 2 - Creates manually the image file header, based on the properties obtained from the image; 3 - Retrieved the image binaries from the hBitmap handle; 4 - Joins it all, and rebuilds the image.
GETPICTUREVALFROMHBITMAP Parameters: NONE !
* Sample 4 - Using the GetPictureValfromHBitmap
*
* Load the image to GDI+
* Call the Bitmap.GetPictureValfromhBitmap() function
DO LOCFILE("System.Prg")
LOCAL loBmp as xfcBitmap
* Obtaining the PictureVal directly
WITH _Screen.System.Drawing
loBmp = .Bitmap.FromFile(GETPICT())
Thisform.Image1.PictureVal = loBmp.GetPictureValFromhBitmap()
ENDWITH
5 - IMAGECANVAS object
Since the Alpha versions of GdiPlus-X we are already using the PictureVal property, direct drawing on an Image object. I already wrote a post about it, please refer to Direct Draw with the Image Canvas from GdiPlus-X for more information, and samples.
There's more to say about the image canvas, but this I'll leave for the future, when some new features will be available.
DOWNLOAD SAMPLE
Click here to download the source code from the samples above shown. Please note that when you click on an button for the first time, it will first look for the GdiPlusX "SYSTEM.PRG" file. Please go to that directory and click "OK". Next, select any image to show in the image object
In one of my next posts, I'll show how easy it is to do the opposite: sending the image binaries to a stream, and loading it to GDI+
Enjoy !
RELATED LINKS:
CALVIN HSIA - Use an IStream object to avoid disk access
Direct Draw with the Image Canvas from GdiPlus-X
MSDN - Memory Stream Class
MSDN - Memory Stream Constructor