Creating and Saving a Multiple-Frame Image
With certain file formats, you can save multiple images (frames) to a single file. For example, you can save several pages to a single TIFF file. To save the first page, call the
GdipSaveImageToFile function. To save subsequent pages, call the
GdipSaveAddImage function.
The following console application creates a TIFF file with three pages. The images that become the pages of the TIFF file come from three disk files. The code first constructs three Image objects: multi, page2 and page3. As the individual pages are added to the multiImage object, they are also added to the disk file Multiframe.tif.
Note that the code calls
GdipSaveImageToFile (not
GdipSaveAddImage) to save the first page. The second argument passed to the
GdipSaveImageToFile function is the name of the disk file that will eventually contain several frames. The third argument passed to the
GdipSaveImageToFile function specifies the encoder that will be used to convert the data in the multiImage object to the format (in this case TIFF) required by the disk file.
That same encoder is used automatically by all subsequent calls to the
GdipSaveAddImage function of the multiImage object.
The fourth argument passed to the
GdipSaveImageToFile function is the address of an
EncoderParameters structure The
EncoderParameters structure has an array that contains a single
EncoderParameter structure. The
Guid member of that
EncoderParameter structure is set to
$EncoderSaveFlag. The
Value member of the
EncoderParameter structure points to a DWORD variable that contains the value
%EncoderValueMultiFrame.
The code saves the second and third pages by calling the
GdipSaveAddImage function. The first argument passed to the
GdipSaveAddImage function is the address of the multi object. The second argument is the address of an
Image object. The image in that
Image object is added to the multiImage object and is also added to the Multiframe.tif disk file. The third argument passed to the
GdipSaveAddImage function is the address of the same
EncoderParameters structure that was used by the
GdipSaveImageToFile function. The difference is that the DWORD pointed to by the
Value member now contains the value
%EncoderValueFrameDimensionPage. Finally, the file is closed calling the
GdipSaveAdd function with the
Value member of the
EncoderParameter structure pointing to a DWORD variable that contains the value
%EncoderValueFlush.
C++
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid); // helper function
INT main()
{
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
EncoderParameters encoderParameters;
ULONG parameterValue;
Status stat;
// An EncoderParameters object has an array of
// EncoderParameter objects. In this case, there is only
// one EncoderParameter object in the array.
encoderParameters.Count = 1;
// Initialize the one EncoderParameter object.
encoderParameters.Parameter[0].Guid = EncoderSaveFlag;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = ¶meterValue;
// Get the CLSID of the TIFF encoder.
CLSID encoderClsid;
GetEncoderClsid(L"image/tiff", &encoderClsid);
// Create four image objects.
Image* multi = new Image(L"Shapes.bmp");
Image* page2 = new Image(L"Cereal.gif");
Image* page3 = new Image(L"Iron.jpg");
Image* page4 = new Image(L"House.png");
// Save the first page (frame).
parameterValue = EncoderValueMultiFrame;
stat = multi->Save(L"MultiFrame.tif", &encoderClsid, &encoderParameters);
if(stat == Ok)
printf("Page 1 saved successfully.\n");
// Save the second page (frame).
parameterValue = EncoderValueFrameDimensionPage;
stat = multi->SaveAdd(page2, &encoderParameters);
if(stat == Ok)
printf("Page 2 saved successfully.\n");
// Save the third page (frame).
parameterValue = EncoderValueFrameDimensionPage;
stat = multi->SaveAdd(page3, &encoderParameters);
if(stat == Ok)
printf("Page 3 saved successfully.\n");
// Save the fourth page (frame).
parameterValue = EncoderValueFrameDimensionPage;
stat = multi->SaveAdd(page4, &encoderParameters);
if(stat == Ok)
printf("Page 4 saved successfully.\n");
// Close the multiframe file.
parameterValue = EncoderValueFlush;
stat = multi->SaveAdd(&encoderParameters);
if(stat == Ok)
printf("File closed successfully.\n");
delete multi;
delete page2;
delete page3;
delete page4;
GdiplusShutdown(gdiplusToken);
return 0;
}
PowerBASICThe main function relies on the helper function
GdiPlusGetEncoderClsid to retrieve the guid of the TIFF encoder.
#COMPILE EXE
#DIM ALL
#INCLUDE "GDIPLUS.INC"
#INCLUDE "GDIPUTILS.INC"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL hStatus AS LONG
LOCAL token AS DWORD
LOCAL StartupInput AS GdiplusStartupInput
LOCAL EncoderClsid AS GUID
LOCAL pMulti AS DWORD
LOCAL pPage2 AS DWORD
LOCAL pPage3 AS DWORD
LOCAL eps AS EncoderParameters
LOCAL ep AS EncoderParameter
LOCAL parameterValue AS DWORD
LOCAL strFileName AS STRING
' // Initialize GDI+
StartupInput.GdiplusVersion = 1
hStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
IF hStatus THEN
PRINT "Error initializing GDI+"
EXIT FUNCTION
END IF
' // An EncoderParameters object has an array of
' // EncoderParameter objects. In this case, there is only
' // one EncoderParameter object in the array.
eps.Count = 1
' // Initialize the one EncoderParameter object.
eps.Parameter(0).pGuid = $EncoderSaveFlag
eps.Parameter(0).dwType = %EncoderParameterValueTypeLong
eps.Parameter(0).NumberOfValues = 1
eps.Parameter(0).Value = VARPTR(parameterValue)
' // Get the CLSID of the TIFF encoder.
EncoderClsid = GUID$(GdiPlusGetEncoderClsid("image/tiff"))
' // Create three image objects.
strFileName = UCODE$("Shapes.bmp")
hStatus = GdipLoadImageFromFile(STRPTR(strFileName), pMulti)
strFileName = UCODE$("Iron.jpg")
hStatus = GdipLoadImageFromFile(STRPTR(strFileName), pPage2)
strFileName = UCODE$("House.png")
hStatus = GdipLoadImageFromFile(STRPTR(strFileName), pPage3)
' // Save the first page (frame).
parameterValue = %EncoderValueMultiFrame
strFileName = UCODE$("Multiframe.tif")
hStatus = GdipSaveImageToFile(pMulti, STRPTR(strFileName), EncoderClsid, eps)
IF hStatus = %StatusOk THEN PRINT "Page 1 saved successfully"
' // Save the second page (frame).
parameterValue = %EncoderValueFrameDimensionPage
hStatus = GdipSaveAddImage(pMulti, pPage2, eps)
IF hStatus = %StatusOk THEN PRINT "Page 2 saved successfully"
' // Save the third page (frame).
parameterValue = %EncoderValueFrameDimensionPage
hStatus = GdipSaveAddImage(pMulti, pPage3, eps)
IF hStatus = %StatusOk THEN PRINT "Page 3 saved successfully"
' // Close the multiframe file.
parameterValue = %EncoderValueFlush
hStatus = GdipSaveAdd(pMulti, eps)
IF hStatus = %StatusOk THEN PRINT "File closed successfully"
' // Cleanup
IF pPage3 THEN GdipDisposeImage(pPage3)
IF pPage2 THEN GdipDisposeImage(pPage2)
IF pMulti THEN GdipDisposeImage(pMulti)
' // Shutdown GDI+
GdiplusShutdown token
WAITKEY$
END FUNCTION
' ========================================================================================