實作 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上是必要的。 我們將討論IWICBitmapEncoder 上選擇性的方法,請參閱 IWICBitmapFrameEncode一節中最常實作的方法。

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

Initialize

Initialize 是在 IWICBitmapEncoder 具現化之後叫用的第一個方法。 影像資料流程會傳遞至編碼器,而呼叫端可以選擇性地指定快取選項。 在解碼器的情況下,資料流程是唯讀的,但傳遞至編碼器的資料流程是可寫入的資料流程,編碼器會將所有影像資料和中繼資料序列化到其中。 編碼器上的快取選項也不同。

enum WICBitmapEncoderCacheOption
{
   WICBitmapEncoderCacheInMemory,
   WICBitmapEncoderCacheTempFile,
   WICBitmapEncoderNoCache
}

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

GetContainerFormat

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

GetEncoderInfo

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

請參閱GetDecoderInfo實作 IWICBitmapDecoder中的範例。

CreateNewFrame

CreateNewFrameIWICBitmapDecoderGetFrame的編碼器對應專案。 這個方法會傳回 IWICBitmapFrameEncode 物件,這是實際序列化容器內特定框架之影像資料的物件。

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

若要具現化 IPropertyBag2 物件,您必須先建立 PROPBAG2 結構,以指定編碼器支援的每個編碼器選項,以及每個屬性的資料類型。 然後,您必須實作 IPropertyBag2 物件,以在寫入時強制執行每個屬性的值範圍,並協調任何衝突或重迭的值。 針對一組非衝突的編碼器選項,您可以叫用 CreateEncoderPropertyBag 方法,此方法會使用您在 PROPBAG2 結構中指定的屬性來建立簡單的 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 值範圍
Lossless VT_BOOL True/False
ImageQuality VT_R4 0.0-1.0
CompressionQuality VT_R4 0.0-1.0
BitmapTransform 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

Commit 是您在將所有影像資料和中繼資料序列化至資料流程之後所呼叫的方法。 您應該使用此方法將預覽影像資料序列化至資料流程,以及任何適用的全域縮圖、中繼資料、調色盤或其他專案。 這個方法不應該關閉檔案資料流程,因為開啟資料流程的應用程式預期會關閉它。

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

SetPreview

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

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

參考

IWICBitmapEncoder

IWICBitmapFrameEncode

概念

編碼器介面

實作 IWICBitmapCodecProgressNotification (Encoder)

如何撰寫WIC-Enabled CODEC

Windows 映像處理元件概觀