Elenco di parametri e valori per tutti i codificatori
L'applicazione console seguente elenca tutti i parametri supportati dai vari codificatori installati nel computer. La funzione principale chiama GetImageEncoders per individuare i codificatori disponibili. Per ogni codificatore disponibile, la funzione main chiama la funzione helper ShowAllEncoderParameters.
La funzione ShowAllEncoderParameters chiama il metodo Image::GetEncoderParameterList per individuare i parametri supportati da un determinato codificatore. Per ogni parametro supportato, la funzione elenca la categoria, il tipo di dati e il numero di valori. La funzione ShowAllEncoderParameters si basa su due funzioni helper: EncoderParameterCategoryFromGUID e 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
Quando si esegue l'applicazione console precedente, si ottiene un output simile al seguente:
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.
È possibile trarre le conclusioni seguenti esaminando l'output del programma precedente:
- Il codificatore JPEG supporta le categorie di parametri Transformation, Quality, LuminanceTable e ChrominanceTable.
- Il codificatore TIFF supporta le categorie di parametri Compression, ColorDepth e SaveFlag.
È anche possibile visualizzare il numero di valori accettabili per ogni categoria di parametri. Ad esempio, è possibile notare che la categoria di parametri ColorDepth (codec TIFF) ha cinque valori di tipo ULONG. Il codice seguente elenca i cinque valori. Si supponga che pEncoderParameters sia un puntatore a un oggetto EncoderParameters che rappresenta il codificatore TIFF.
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]);
}
L'output del codice precedente è il seguente:
The allowable values for ColorDepth are
1
4
8
24
32
Nota
In alcuni casi, i valori in un oggetto EncoderParameter sono i valori numerici degli elementi dell'enumerazione EncoderValue . Tuttavia, i numeri nell'elenco precedente non sono correlati all'enumerazione EncoderValue . I numeri indicano 1 bit per pixel, 2 bit per pixel e così via.
Se si scrive codice simile all'esempio precedente per esaminare i valori consentiti per le altre categorie di parametri, si otterrà un risultato simile al seguente.
Parametro del codificatore JPEG | Valori consentiti |
---|---|
Trasformazione | EncoderValueTransformRotate90 EncoderValueTransformRotate180 EncoderValueTransformRotate270 EncoderValueTransformFlipHorizontal EncoderValueTransformFlipVertical |
Qualità | da 0 a 100 |
Parametro del codificatore TIFF | Valori consentiti |
---|---|
Compressione | EncoderValueCompressionLZW EncoderValueCompressionCCITT3 EncoderValueCompressionCCITT4 EncoderValueCompressionRle EncoderValueCompressionNone |
ColorDepth | 1, 4, 8, 24, 32 |
SaveFlag | EncoderValueMultiFrame |
Nota
Se la larghezza e l'altezza di un'immagine JPEG sono multipli di 16, è possibile applicare qualsiasi trasformazione consentita dalla categoria di parametri EncoderTransformation (ad esempio, rotazione di 90 gradi) senza perdita di informazioni.