共用方式為


實現 IWICBitmapEncoder

IWICBitmapEncoder

這個介面是與 IWICBitmapDecoder 介面的對應專案,而且是編碼影像檔案的起點。 就像 IWICBitmapDecoder 用來從映像容器擷取容器層級屬性和個別框架一樣,IWICBitmapEncoder 用於設定容器層級屬性,並將個別影像框架串行化為容器。 您可以在容器層級編碼器類別上實作這個介面。

interface IWICBitmapEncoder : public IUnknown
{
   // Required methods
   HRESULT Initialize ( IStream *pIStream,
              WICBitmapEncoderCacheOption cacheOption );
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetEncoderInfo ( IWICBitmapEncoderInfo **pIEncoderInfo );
   HRESULT CreateNewFrame ( IWICBitmapFrameEncode **ppIFrameEncode,
              IPropertyBag2 **ppIEncoderOptions );
   HRESULT Commit ( void );

   // Optional methods
   HRESULT SetPreview ( IWICBitmapSource *pIPreview );
   HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
   HRESULT SetColorContexts ( UINT cCount,
              IWICColorContext **ppIColorContext );
   HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter 
              **ppIMetadataQueryWriter );
   HRESULT SetPalette ( IWICPalette *pIPalette);
};

實作 IWICBitmapDecoder中所述,某些影像格式具有全域縮圖、色彩內容或元數據,而許多影像格式則僅依據每個畫面提供這些格式。 因此,在 IWICBitmapEncoder上設定這些方法是選擇性的,但在 IWICBitmapFrameEncode上是必要的。 我們將在 IWICBitmapFrameEncode一節中討論有關 IWICBitmapEncoder 的可選方法,這些方法最常在此實作。

如果您不支援全域縮圖,請從 IWICBitmapEncoder上的 SetThumbnail 方法傳回WINCODEC_ERR_CODECNOTHUMBNAIL。 如果您不支援容器層級調色盤,或您編碼的映像沒有索引格式,請從 SetPalette 方法傳回WINCODEC_ERR_PALETTEUNAVAILABLE。 針對任何其他不支援的方法,返回WINCODEC_ERR_UNSUPPORTEDOPERATION。

初始化

實例化之後,IWICBitmapEncoder 上的第一個被叫用的方法是 Initialize。 影像數據流會傳遞至編碼器,而呼叫端可以選擇性地指定快取選項。 在譯碼器的情況下,數據流是唯讀的,但傳遞至編碼器的數據流是可寫入的數據流,編碼器會串行化所有影像數據和元數據。 編碼器上的快取選項也不同。

enum WICBitmapEncoderCacheOption
{
   WICBitmapEncoderCacheInMemory,
   WICBitmapEncoderCacheTempFile,
   WICBitmapEncoderNoCache
}

應用程式可以選擇要求編碼器在記憶體中快取映像數據、將它快取在暫存盤中,或直接寫入磁碟檔案中,而不需要快取。 當系統要求快取暫存盤中的數據時,編碼器應該在磁碟上建立暫存盤,並直接寫入該檔案,而不需在記憶體中快取。 當呼叫端選取無快取選項時,每個畫面必須依序提交,才能建立下一個畫面。

取得容器格式

GetContainerFormat 的實作方式與 實作 IWICBitmapDecoder中的 GetContainerFormat 方法相同。

取得編碼器資訊

GetEncoderInfo 會傳回 IWICBitmapEncoderInfo 物件。 若要取得 IWICBitmapEncoderInfo 物件,只要將編碼器的 GUID 傳遞至 IWICImagingFactory上的 CreateComponentInfo 方法,然後要求 IWICBitmapEncoderInfo 介面。

請參閱 實作 IWICBitmapDecoderGetDecoderInfo中的範例。

CreateNewFrame

CreateNewFrameIWICBitmapDecoder上的 GetFrame 的編碼器對應項。 這個方法會傳回 IWICBitmapFrameEncode 物件,這是實際串行化容器內特定框架影像數據的物件。

Windows 映射元件 (WIC) 的優點之一是,它為應用程式提供一層抽象概念,讓應用程式能夠以相同方式使用所有影像格式。 不過,並非所有影像格式都完全相同。 某些影像格式具有其他格式所不具備的功能。 若要讓應用程式能夠利用這些獨特的功能,您必須為編解碼器提供公開它們的方式。 這是編碼器選項的目的。 如果您的編解碼器支援任何編碼器選項,您應該建立 IPropertyBag2 物件來公開您支援的編碼器選項,並在此方法的 ppIEncoderOptions 參數中傳回它。 呼叫端接著可以使用這個 IPropertyBag2 對象來判斷編解碼器支援的編碼器選項。 如果呼叫端想要為任何支援的編碼器選項指定值,它們會將值指派給 IPropertyBag2 物件中的相關屬性,並將它傳遞給其 Initialize 方法中新建立的 IWICBitmapFrameEncode 物件。

若要具現化 IPropertyBag2 物件,您必須先建立PROPBAG2結構,以指定編碼器支援的每個編碼器選項,以及每個屬性的數據類型。 然後,您必須實作 IPropertyBag2 物件,以強制執行寫入時每個屬性的值範圍,並協調任何衝突或重疊的值。 針對非衝突編碼器選項的簡單集合,您可以使用您在PROPBAG2結構中指定的屬性,叫用 CreateEncoderPropertyBagg 方法,以建立簡單的 IPropertyBag2 物件。 您仍然必須強制執行值的範圍。 如需更進階的編碼器選項,或如果您需要協調衝突的值,您應該撰寫自己的 IPropertyBag2 實作。

UINT cuiPropertyCount = 0;
IPropertyBag2* pPropertyBag = NULL;
PROPBAG2* pPropBagOptions;
HRESULT hr;

// Insert code here to initialize piPropertyBag with the 
// supported options for your encoder, and to initialize 
// cuiPropertyCount to the number of encoder option properties
// you are exposing.
...

hr = pComponentFactory->CreateEncoderPropertyBag( 
   pPropBagOptions, cuiPropertyCount, &pPropertyBag);

WIC 提供一組小型標準編碼器選項,供一些常見的影像格式使用。 所有標準編碼器選項都是選擇性的,而且不需要編解碼器來支援其中任何一個選項。 其提供為標準選項的原因是,許多應用程式會公開使用者介面,讓使用者在以支援它們的格式儲存圖像檔時指定這些選項。 提供標準的方式來指定這些選項,可讓應用程式輕鬆地以一致的方式與編碼器通訊。 下表列出標準編碼器選項。

編碼器選項 VARTYPE 值範圍
無損 VT_BOOL 真/假
ImageQuality VT_R4 0.0-1.0
壓縮品質 VT_R4 0.0-1.0
位圖轉換 VT_UI1 WICBitmapTransformOptions

 

如果您的編解碼器支援無遺失編碼,您應該將 [無遺失編碼器] 選項公開為應用程式要求影像進行無遺失編碼的方式。 如果呼叫端將此屬性設定為 True,則您應該忽略 ImageQuality 選項,並以無損失方式編碼影像。

ImageQuality 選項可讓應用程式指定用來編碼影像的逼真度。 此選項可讓使用者在影像品質與速度和/或檔案大小之間進行取捨。 JPEG 是支援此取捨的影像格式範例。 值為 0.0 表示精確度低重要性,編碼器應該使用最遺失的演算法。 值為 1.0 表示精確度是最重要的,編碼器應保留可能的最高精確度。 (視您的編解碼器而定,這可能與 [無遺失] 選項同義。不過,如果您的編解碼器支援無損失編碼,且 [無遺失] 選項設定為 True,則應該忽略 ImageQuality 選項。

CompressionQuality 選項可讓應用程式指定編碼影像時要使用的壓縮效率。 非常有效率的演算法可能會產生較小的圖像檔,其品質與較不具效率的壓縮演算法相同,但編碼可能需要較長的時間。 此選項可讓使用者指定檔案大小與編碼速度之間的取捨,同時保留相同的品質層級。 TIFF 是支援此取捨的影像格式範例。 (請注意,JPEG 之類的格式支援不同層級的壓縮,但較高的壓縮速率會導致影像品質較低。因此,JPEG 影像格式會公開 ImageQuality 選項,而不是 CompressionQuality 選項。此選項的值為 0.0,表示您應該儘快壓縮影像,而不會降低逼真度,代價是較大的檔案大小。 值 1.0 表示您應該建立最小的可能檔案大小(在相同品質層級),不論編碼可能需要多久的時間。 編解碼器可以同時支援 ImageQuality 選項和 CompressionQuality 選項,其中 ImageQuality 選項會指定可接受的損失程度,而 CompressionQuality 選項會在指定的品質層級提供大小/速度取捨。

BitmapTransform 選項提供方法,讓呼叫者在編碼時指定旋轉角度或垂直或水準翻轉方向。 用來指定所要求轉換的 WICBitmapTransformOptions 列舉與透過 IWICBitmapSourceTransform 介面譯碼期間要求轉換時所使用的列舉相同。

請注意,編碼器不限於標準編碼器選項。 編碼器選項的目的是要讓編碼器公開其功能,而且您可以公開的功能類型沒有限制。 請確定您的編碼器選項已妥善記載。 雖然應用程式可以使用您從這個方法傳回的屬性包來探索您支援之選項的名稱、類型和值範圍,但他們找出其意義或如何在使用者介面中公開它們的唯一方式,就是來自您的檔。

承諾

Commit 是在所有影像數據和元數據被串行化至數據流後所呼叫的方法。 您應該使用這個方法,將預覽影像數據序列化至資料流,並視需要將任何全域縮圖、元數據、調色盤或其他項目序列化。 這個方法不應該關閉檔案數據流,因為開啟數據流的應用程式應該會關閉它。

IWICBitmapFrameEncode:Commit 方法上的區段詳細說明 IWICBitmapEncoderCacheOptions 如何影響此方法的行為。

設定預覽

SetPreview 用來建立影像預覽。 雖然並非絕對要求每個影像都有預覽,但強烈建議使用。 現代數位相機和掃描儀會產生非常高解析度的影像,這些影像往往非常大,因此,需要大量的處理時間來譯碼。 新一代相機的影像將更大。 最好是提供較小的較低解析度版本的影像,通常是以 JPEG 格式,在使用者要求影像時快速譯碼並顯示。 應用程式可以在要求譯碼實際影像之前要求預覽,為使用者提供更好的體驗,並在等候譯碼實際影像時顯示影像的螢幕大小表示法。 雖然編解碼器應該提供預覽,但不支援 IWICBitmapSourceTransform 的編解碼器絕對應該這樣做。

如果您提供 JPEG 預覽版,就不需要撰寫 JPEG 編碼器來編碼它。 您應該委派給隨附於 WIC 平臺的 JPEG 編碼器,以編碼預覽和縮圖。

參考

IWICBitmapEncoder

IWICBitmapFrameEncode

概念

編碼器介面

實作 IWICBitmapCodecProgressNotification (Encoder)

如何撰寫 WIC-Enabled CODEC

Windows 映射元件概觀