Determining the Parameters Supported by an Encoder

The Image class provides the Image::GetEncoderParameterList method so that you can determine the parameters that are supported by a given image encoder. The Image::GetEncoderParameterList method returns an array of EncoderParameter objects. You must allocate a buffer to receive that array before you call Image::GetEncoderParameterList. You can call Image::GetEncoderParameterListSize to determine the size of the required buffer.

The following console application obtains the parameter list for the JPEG encoder. The main function relies on the helper function GetEncoderClsid, which is shown in Retrieving the Class Identifier for an Encoder.

#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);

   // Create Bitmap (inherited from Image) object so that we can call
   // GetParameterListSize and GetParameterList.
   Bitmap* bitmap = new Bitmap(1, 1);

   // Get the JPEG encoder CLSID.
   CLSID encoderClsid;
   GetEncoderClsid(L"image/jpeg", &encoderClsid);

   // How big (in bytes) is the JPEG encoder's parameter list?
   UINT listSize = 0; 
   listSize = bitmap->GetEncoderParameterListSize(&encoderClsid);
   printf("The parameter list requires %d bytes.\n", listSize);

   // Allocate a buffer large enough to hold the parameter list.
   EncoderParameters* pEncoderParameters = NULL;
   pEncoderParameters = (EncoderParameters*)malloc(listSize);

   // Get the parameter list for the JPEG encoder.
   bitmap->GetEncoderParameterList(
      &encoderClsid, listSize, pEncoderParameters);

   // pEncoderParameters points to an EncoderParameters object, which
   // has a Count member and an array of EncoderParameter objects.
   // How many EncoderParameter objects are in the array?
   printf("There are %d EncoderParameter objects in the array.\n", 
      pEncoderParameters->Count);

   free(pEncoderParameters);
   delete(bitmap);
   GdiplusShutdown(gdiplusToken);
   return 0;
}

When you run the preceding console application, you get an output similar to the following:

The parameter list requires 172 bytes.
There are 4 EncoderParameter objects in the array.

Each of the EncoderParameter objects in the array has the following four public data members:

The following code is a continuation of the console application shown in the preceding example. The code looks at the second EncoderParameter object in the array returned by Image::GetEncoderParameterList. The code calls StringFromGUID2, which is a system function declared in Objbase.h, to convert the Guid member of the EncoderParameter object to a string.

// Look at the second (index 1) EncoderParameter object in the array.
printf("Parameter[1]\n");

WCHAR strGuid[39];
StringFromGUID2(pEncoderParameters->Parameter[1].Guid, strGuid, 39);
wprintf(L"   The GUID is %s.\n", strGuid);

printf("   The value type is %d.\n", 
   pEncoderParameters->Parameter[1].Type);

printf("   The number of values is %d.\n",
   pEncoderParameters->Parameter[1].NumberOfValues);

The preceding code produces the following output:

Parameter[1]
   The GUID is {1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}.
   The value type is 6.
   The number of values is 1.

You can look up the GUID in Gdiplusimaging.h and find out that the category of this EncoderParameter object is EncoderQuality. You can use this category (EncoderQuality) of parameter to set the compression level of a JPEG image.

In Gdiplusenums.h, the EncoderParameterValueType enumeration indicates that data type 6 is ValueLongRange. A long range is a pair of ULONG values.

The number of values is one, so we know that the Value member of the EncoderParameter object is a pointer to an array that has one element. That one element is a pair of ULONG values.

The following code is a continuation of the console application that is shown in the preceding two examples. The code defines a data type called PLONGRANGE (pointer to a long range). A variable of type PLONGRANGE is used to extract the minimum and maximum values that can be passed as a quality setting to the JPEG encoder.

typedef struct
   {
      long min;
      long max;
   }* PLONGRANGE;

   PLONGRANGE pLongRange = 
      (PLONGRANGE)(pEncoderParameters->Parameter[1].Value);

   printf("   The minimum possible quality value is %d.\n",
      pLongRange->min);

   printf("   The maximum possible quality value is %d.\n",
      pLongRange->max);

The preceding code produces the following output:

The minimum possible quality value is 0.
The maximum possible quality value is 100.

In the preceding example, the value returned in the EncoderParameter object is a pair of ULONG values that indicate the minimum and maximum possible values for the quality parameter. In some cases, the values returned in an EncoderParameter object are members of the EncoderValue enumeration. The following topics discuss the EncoderValue enumeration and methods for listing possible parameter values in more detail: