• Welcome to Jose's Read Only Forum 2023.
 

GDI+: GdipSaveAddImage

Started by José Roca, June 23, 2008, 02:51:59 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
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 = &parameterValue;

   // 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;
}


PowerBASIC

The 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
' ========================================================================================