Freigeben über


Auflisten von Parametern und Werten für alle Encoder

Die folgende Konsolenanwendung listet alle Parameter auf, die von den verschiedenen auf dem Computer installierten Encodern unterstützt werden. Die Standard-Funktion ruft GetImageEncoders auf, um zu ermitteln, welche Encoder verfügbar sind. Für jeden verfügbaren Encoder ruft die funktion Standard die Hilfsfunktion ShowAllEncoderParameters auf.

Die ShowAllEncoderParameters-Funktion ruft die Image::GetEncoderParameterList-Methode auf, um zu ermitteln, welche Parameter von einem bestimmten Encoder unterstützt werden. Für jeden unterstützten Parameter listet die Funktion die Kategorie, den Datentyp und die Anzahl der Werte auf. Die ShowAllEncoderParameters-Funktion basiert auf zwei Hilfsfunktionen: EncoderParameterCategoryFromGUID und ValueTypeFromULONG.

#include <windows.h>
#include <gdiplus.h>
#include <strsafe.h>
using namespace Gdiplus;

// Helper functions
void ShowAllEncoderParameters(ImageCodecInfo*);
HRESULT EncoderParameterCategoryFromGUID(GUID guid, WCHAR* category, UINT maxChars);
HRESULT ValueTypeFromULONG(ULONG index, WCHAR* strValueType, UINT maxChars);

INT main()
{
   // Initialize GDI+
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR gdiplusToken;
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   UINT  num;        // Number of image encoders
   UINT  size;       // Size of the image encoder array in bytes

   ImageCodecInfo* pImageCodecInfo;

   // How many encoders are there?
   // How big (in bytes) is the array of all ImageCodecInfo objects?
   GetImageEncodersSize(&num, &size);

   // Create a buffer large enough to hold the array of ImageCodecInfo
   // objects that will be returned by GetImageEncoders.
   pImageCodecInfo = (ImageCodecInfo*)(malloc(size));

   // GetImageEncoders creates an array of ImageCodecInfo objects
   // and copies that array into a previously allocated buffer. 
   // The third argument, imageCodecInfos, is a pointer to that buffer. 
   GetImageEncoders(num, size, pImageCodecInfo);
    
   // For each ImageCodecInfo object in the array, show all parameters.
   for(UINT j = 0; j < num; ++j)
   { 
      ShowAllEncoderParameters(&(pImageCodecInfo[j]));
   }

   GdiplusShutdown(gdiplusToken);
   return 0;
}


/////////////////////////////////////////////////
// Helper functions

VOID ShowAllEncoderParameters(ImageCodecInfo* pImageCodecInfo)
{
   CONST MAX_CATEGORY_LENGTH = 50;
   CONST MAX_VALUE_TYPE_LENGTH = 50;
   WCHAR strParameterCategory[MAX_CATEGORY_LENGTH] = L"";
   WCHAR strValueType[MAX_VALUE_TYPE_LENGTH] = L"";

   wprintf(L"\n\n%s\n", pImageCodecInfo->MimeType);

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

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

   if(listSize == 0)
      return;

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

   if(pEncoderParameters == NULL)
      return;

   // Get the parameter list for the encoder.
   bitmap.GetEncoderParameterList(
      &pImageCodecInfo->Clsid, 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);

   // For each EncoderParameter object in the array, list the
   // parameter category, data type, and number of values.
   for(UINT k = 0; k < pEncoderParameters->Count; ++k)
   {
      EncoderParameterCategoryFromGUID(
         pEncoderParameters->Parameter[k].Guid, strParameterCategory, MAX_CATEGORY_LENGTH);

      ValueTypeFromULONG(
         pEncoderParameters->Parameter[k].Type, strValueType, MAX_VALUE_TYPE_LENGTH);

      printf("    Parameter[%d]\n", k);
      wprintf(L"      The category is %s.\n", strParameterCategory);
      wprintf(L"      The data type is %s.\n", strValueType);

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

   free(pEncoderParameters);
} // ShowAllEncoderParameters


HRESULT EncoderParameterCategoryFromGUID(GUID guid, WCHAR* category, UINT maxChars)
{
   HRESULT hr = E_FAIL;

   if(guid == EncoderCompression)
      hr = StringCchCopyW(category, maxChars, L"Compression");
   else if(guid == EncoderColorDepth)
      hr = StringCchCopyW(category, maxChars, L"ColorDepth");
   else if(guid == EncoderScanMethod)
      hr = StringCchCopyW(category, maxChars, L"ScanMethod");
   else if(guid == EncoderVersion)
      hr = StringCchCopyW(category, maxChars, L"Version");
   else if(guid == EncoderRenderMethod)
      hr = StringCchCopyW(category, maxChars, L"RenderMethod");
   else if(guid == EncoderQuality)
      hr = StringCchCopyW(category, maxChars, L"Quality");
   else if(guid == EncoderTransformation)
      hr = StringCchCopyW(category, maxChars, L"Transformation");
   else if(guid == EncoderLuminanceTable)
      hr = StringCchCopyW(category, maxChars, L"LuminanceTable");
   else if(guid == EncoderChrominanceTable)
      hr = StringCchCopyW(category, maxChars, L"ChrominanceTable");
   else if(guid == EncoderSaveFlag)
      hr = StringCchCopyW(category, maxChars, L"SaveFlag");
   else
      hr = StringCchCopyW(category, maxChars, L"Unknown category");

   return hr;
} // EncoderParameterCategoryFromGUID


HRESULT ValueTypeFromULONG(ULONG index, WCHAR* strValueType, UINT maxChars)
{
   HRESULT hr = E_FAIL;

   WCHAR* valueTypes[] = {
      L"Nothing",                  // 0
      L"ValueTypeByte",            // 1
      L"ValueTypeASCII",           // 2
      L"ValueTypeShort",           // 3
      L"ValueTypeLong",            // 4
      L"ValueTypeRational",        // 5
      L"ValueTypeLongRange",       // 6
      L"ValueTypeUndefined",       // 7
      L"ValueTypeRationalRange"};  // 8

   hr = StringCchCopyW(strValueType, maxChars, valueTypes[index]);
   return hr;

} // ValueTypeFromULONG

Wenn Sie die vorherige Konsolenanwendung ausführen, erhalten Sie eine Ausgabe ähnlich der folgenden:

image/bmp
  The parameter list requires 0 bytes.

image/jpeg
  The parameter list requires 172 bytes.
  There are 4 EncoderParameter objects in the array.
    Parameter[0]
      The category is Transformation.
      The data type is Long.
      The number of values is 5.
    Parameter[1]
      The category is Quality.
      The data type is LongRange.
      The number of values is 1.
    Parameter[2]
      The category is LuminanceTable.
      The data type is Short.
      The number of values is 0.
    Parameter[3]
      The category is ChrominanceTable.
      The data type is Short.
      The number of values is 0.

image/gif
  The parameter list requires 0 bytes.

image/tiff
  The parameter list requires 160 bytes.
  There are 3 EncoderParameter objects in the array.
    Parameter[0]
      The category is Compression.
      The data type is Long.
      The number of values is 5.
    Parameter[1]
      The category is ColorDepth.
      The data type is Long.
      The number of values is 5.
    Parameter[2]
      The category is SaveFlag.
      The data type is Long.
      The number of values is 1.

image/png
  The parameter list requires 0 bytes.

Sie können die folgenden Schlussfolgerungen ziehen, indem Sie die vorherige Programmausgabe untersuchen:

  • Der JPEG-Encoder unterstützt die Parameterkategorien Transformation, Quality, LuminanceTable und ChrominanceTable.
  • Der TIFF-Encoder unterstützt die Parameterkategorien Compression, ColorDepth und SaveFlag.

Sie können auch die Anzahl der zulässigen Werte für jede Parameterkategorie anzeigen. Sie können beispielsweise sehen, dass die ColorDepth-Parameterkategorie (TIFF-Codec) fünf Werte vom Typ ULONG aufweist. Der folgende Code listet diese fünf Werte auf. Angenommen , pEncoderParameters ist ein Zeiger auf ein EncoderParameters-Objekt , das den TIFF-Encoder darstellt.

ULONG* pUlong = (ULONG*)(pEncoderParameters->Parameter[1].Value);
ULONG numVals = pEncoderParameters->Parameter[1].NumberOfValues;
printf("\nThe allowable values for ColorDepth are\n");

for(ULONG k = 0; k < numVals; ++k)
{
   printf("  %u\n", pUlong[k]);
}
            

Der oben genannte Code erzeugt die folgende Ausgabe:

The allowable values for ColorDepth are
  1
  4
  8
  24
  32
            

Hinweis

In einigen Fällen sind die Werte in einem EncoderParameter-Objekt die numerischen Werte von Elementen der EncoderValue-Enumeration . Die Zahlen in der vorherigen Liste beziehen sich jedoch nicht auf die EncoderValue-Enumeration . Die Zahlen bedeuten 1 Bit pro Pixel, 2 Bit pro Pixel usw.

 

Wenn Sie Code ähnlich dem vorherigen Beispiel schreiben, um die zulässigen Werte für die anderen Parameterkategorien zu untersuchen, erhalten Sie ein Ergebnis ähnlich dem folgenden.

JPEG-Encoderparameter Zulässige Werte
Transformation EncoderValueTransformRotate90 EncoderValueTransformRotate180
  EncoderValueTransformRotate270
  EncoderValueTransformFlipHorizontal
  EncoderValueTransformFlipVertical
Qualität 0 bis 100

 

TIFF-Encoderparameter Zulässige Werte
Komprimierung EncoderValueCompressionLZW EncoderValueCompressionCCITT3
  EncoderValueCompressionCCITT4
  EncoderValueCompressionRle
  EncoderValueCompressionNone
ColorDepth 1, 4, 8, 24, 32
SaveFlag EncoderValueMultiFrame

 

Hinweis

Wenn die Breite und Höhe eines JPEG-Bilds ein Vielfaches von 16 sind, können Sie jede der Transformationen anwenden, die von der EncoderTransformation-Parameterkategorie zulässig sind (z. B. 90-Grad-Drehung), ohne dass Informationen verloren gehen.