列出所有編碼器的參數和值
下列主控台應用程式會列出電腦上安裝的各種編碼器所支援的所有參數。 主要函式會呼叫 GetImageEncoders 來探索有哪些編碼器可供使用。 針對每個可用的編碼器,主要函式會呼叫 Helper 函式 ShowAllEncoderParameters。
ShowAllEncoderParameters 函式會呼叫 Image::GetEncoderParameterList 方法來探索指定編碼器所支援的參數。 針對每個支援的參數,函式會列出類別、資料類型和值數目。 ShowAllEncoderParameters 函式依賴兩個協助程式函式:EncoderParameterCategoryFromGUID 和 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
當您執行上述主控台應用程式時,您會取得類似下列的輸出:
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.
您可以檢查上述程式輸出來繪製下列結論:
- JPEG 編碼器支援 Transformation、Quality、LuminanceTable 和 ChrominanceTable 參數類別。
- TIFF 編碼器支援 Compression、ColorDepth 和 SaveFlag 參數類別。
您也可以查看每個參數類別可接受的值數目。 例如,您可以看到 ColorDepth 參數類別 (TIFF 編解碼器) 有五個 類型 ULONG的值。 下列程式碼會列出這五個值。 假設 pEncoderParameters 是代表 TIFF 編碼器之 EncoderParameters 物件的指標。
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]);
}
前一個程式碼會產生下列輸出:
The allowable values for ColorDepth are
1
4
8
24
32
注意
在某些情況下, EncoderParameter 物件中的值是 EncoderValue 列舉元素的數值。 不過,上述清單中的數位與 EncoderValue 列舉無關。 數位表示每個圖元 1 位、每個圖元 2 位等等。
如果您撰寫的程式碼類似于上述範例,以調查其他參數類別的允許值,您將取得類似下列的結果。
JPEG 編碼器參數 | 允許的值 |
---|---|
轉換 | EncoderValueTransformRotate90 EncoderValueTransformRotate180 EncoderValueTransformRotate270 EncoderValueTransformFlipHorizontal EncoderValueTransformFlipVertical |
品質 | 0 到 100 |
TIFF 編碼器參數 | 允許的值 |
---|---|
壓縮 | EncoderValueCompressionLZW EncoderValueCompressionCCITT3 EncoderValueCompressionCCITT4 EncoderValueCompressionRle EncoderValueCompressionNone |
ColorDepth | 1, 4, 8, 24, 32 |
SaveFlag | EncoderValueMultiFrame |
注意
如果 JPEG 影像的寬度和高度是 16 的倍數,您可以套用 EncoderTransformation 參數類別所允許的任何轉換 (,例如,90 度旋轉) 而不遺失資訊。