實作 IWICBitmapFrameEncode

IWICBitmapFrameEncode

IWICBitmapFrameEncode 是編碼器與 IWICBitmapFrameDecode 介面的對應專案。 您可以在框架層級編碼類別上實作這個介面,這是針對每個畫面執行影像位實際編碼的類別。

interface IWICBitmapFrameEncode : public IUnknown
{
   // Required methods
   HRESULT Initialize ( IPropertyBag2 *pIEncoderOptions );
   HRESULT SetSize ( UINT width,
               UINT height );
   HRESULT SetResolution ( double dpiX,
               double dpiY );
   HRESULT SetPixelFormat (WICPixelFormatGUID *pPixelFormat);
   HRESULT SetColorContexts ( UINT cCount,
               IWICColorContext **ppIColorContext );
   HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter 
               **ppIMetadataQueryWriter );
   HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
   HRESULT WritePixels ( UINT lineCount,
               UINT cbStride,
               UINT cbBufferSize,
               BYTE *pbPixels );
   HRESULT WriteSource ( IWICBitmapSource *pIWICBitmapSource,
               WICRect *prc );
   HRESULT Commit ( void );

// Optional method
   HRESULT SetPalette ( IWICPalette *pIPalette );
};

Initialize

Initialize 是在具現化 IWICBitmapFrameEncode 物件上叫用的第一個方法。 這個方法有一個參數,它可以設定為 Null。 此參數代表編碼器選項,而且是您在容器層級解碼器上CreateNewFrame方法中建立的相同IPropertyBag2實例,並傳回給該方法 pIEncoderOptions 參數中的呼叫端。 此時,您已填入 IPropertyBag2 結構,其中包含代表框架層級編碼器所支援編碼選項的屬性。 呼叫端現在已提供這些屬性的值來指出特定的編碼選項參數,並將相同的物件傳回給您,以初始化 IWICBitmapFrameEncode 物件。 編碼影像位時,您應該套用指定的選項。

SetSize 和 SetResolution

SetSizeSetResolution 是自我說明。 呼叫端會使用這些方法來指定編碼影像的大小和解析度。

SetPixelFormat

SetPixelFormat 可用來要求用來編碼影像的像素格式。 如果不支援要求的像素格式,您應該傳回 pPixelFormat中支援之最接近像素格式的 GUID,這是 in/out 參數。

SetColorCoNtexts

SetColorCoNtexts 可用來指定一或多個有效的色彩內容, (也稱為此影像的色彩設定檔) 。 請務必指定色彩內容,因此稍後解碼影像的應用程式可以將來源色彩設定檔轉換成用來顯示或列印影像之裝置的目的地設定檔。 如果沒有色彩設定檔,就無法在不同的裝置上取得一致的色彩。 當使用者的相片在不同監視器上看起來不同時,這可能會令人感到沮喪,而且無法取得列印以符合他們在畫面上看到的內容。

GetMetadataQueryWriter

GetMetadataQueryWriter 會傳回 IWICMetadataQueryWriter ,應用程式可用來在影像框架的中繼資料區塊中插入或編輯特定中繼資料屬性。

您可以透過數種方式,從IWICComponentFactory具現化IWICMetadataQueryWriter。 您可以從IWICMetadataBlockWriter建立它,從 IWICMetadataBlockReader 在IWICBitmapFrameDecode介面上的GetMetadataQueryReader方法中建立IWICMetadataQueryReader的方式相同。

IWICMetadataQueryWriter* piMetadataQueryWriter = NULL;
HRESULT hr;

hr = m_piComponentFactory->CreateQueryWriterFromBlockWriter( 
      static_cast<IWICMetadataBlockWriter*>(this), 
      &piMetadataQueryWriter);

您也可以從現有的 IWICMetadataQueryReader 建立它,例如使用先前方法取得的 IWICMetadataQueryReader

hr = m_piComponentFactory->CreateQueryWriterFromReader( 
      piMetadataQueryReader, pguidVendor, &piMetadataQueryWriter);

pguidVendor參數可讓您指定特定廠商,讓查詢寫入器在具現化中繼資料寫入器時使用。 例如,如果您提供自己的中繼資料寫入器,您可能會想要指定自己的廠商 GUID。 如果您沒有喜好設定,您可以將 Null 傳遞至此參數。

SetThumbnail

SetThumbnail 可用來提供縮圖。 所有影像都應該在全域、每個畫面或兩者上提供縮圖。 GetThumbnailSetThumbnail方法在容器層級是選擇性的,但如果編解碼器從GetThumbnail方法傳回WINCODEC_ERR_CODECNOTHUMBNAIL,Windows Imaging Component (WIC) 將會叫用 Frame 0 的GetThumbnail方法。 如果任一位置都找不到縮圖,WIC 必須解碼完整的影像,並將其調整為縮圖大小,這可能會導致較大的影像效能降低。

縮圖的大小和解析度應可讓縮圖快速解碼和顯示。 因此,縮圖最常見的是 JPEG 影像。 請注意,如果您針對縮圖使用 JPEG,就不需要撰寫 JPEG 編碼器來編碼它們,或 JPEG 解碼器來解碼它們。 您應該一律委派給隨附于 WIC 平臺的 JPEG 編解碼器,以進行編碼和解碼縮圖。

WritePixels

WritePixels 是用來從記憶體中點陣圖傳入掃描行以進行編碼的方法。 方法會重複呼叫,直到所有掃描行都傳入為止。 lineCount參數會指出要在此呼叫中寫入多少個掃描行。 cbStride參數會指出每個掃描行的位元組數目。 cbBufferSize 表示在 pbPixels 參數中傳遞的緩衝區大小,其中包含要編碼的實際影像位。 如果累積呼叫中的掃描行合併高度大於 SetSize 方法中指定的高度,則傳回WINCODEC_ERR_TOOMANYSCANLINES。

WICBitmapEncoderCacheOptionWICBitmapEncoderCacheInMemory時,掃描行應該快取在記憶體中,直到所有掃描行都傳入為止。 如果編碼器快取選項為 WICBitmapEncoderCacheTempFile,則掃描行應該快取在暫存檔案中,在初始化物件時建立。 在上述任一情況下,在呼叫端呼叫 Commit之前,不應該編碼影像。 如果快取選項是 WICBitmapEncoderNoCache,編碼器應該盡可能編碼掃描行。 (在某些格式中,不可能這樣做,而且必須在呼叫 Commit 之前快取掃描行。)

大部分的原始編解碼器都不會實作 WritePixels,因為它們不支援改變原始檔案中的影像位。 不過,原始編解碼器仍應實作 WritePixels,因為新增中繼資料時,可能會增加檔案的大小,要求在磁片上重寫檔案。 在此情況下,必須能夠複製現有的映射位,這是 WritePixels 方法的功能。

WriteSource

WriteSource 是用來編碼 IWICBitmapSource 物件。 第一個參數是 IWICBitmapSource 物件的指標。 第二個參數是 WICRect,指定要編碼的區域。 只要每個矩形的寬度與要編碼的最終影像寬度相同,這個方法可能會連續呼叫多次。 如果傳入中國參數的矩形寬度與 SetSize 方法中指定的寬度不同,則傳回WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS。 如果累積呼叫中掃描行的合併高度大於 SetSize 方法中指定的高度,則傳回WINCODEC_ERR_TOOMANYSCANLINES。

快取選項的運作方式與先前所述的 WritePixels 方法相同。

Commit

Commit 是將編碼影像位序列化至檔案資料流程的方法,並逐一查看要求它們將中繼資料序列化至資料流程之框架的所有中繼資料寫入器。 在編碼器快取選項為 WICBitmapEncoderCacheInMemory 或 WICBitmapEncoderCacheTempFile 的情況下,此方法也會負責編碼影像,而且當快取選項為 WICBitmapEncoderCacheTempFile 時, Commit 方法也應該刪除用來在編碼之前快取影像資料的暫存檔。

在組成影像的所有掃描行或矩形都已使用 CommitWriteSource 方法傳入之後,一律會叫用這個方法。 透過 WritePixels 或 WriteSource 累積呼叫所組成之最終矩形的大小必須與 SetSize 方法中指定的大小相同。 如果大小不符合預期的大小,這個方法應該會傳回WINCODECERROR_UNEXPECTEDSIZE。

若要逐一查看中繼資料寫入器,並告訴每個中繼資料寫入器序列化其中繼資料,請叫用 GetWriterByIndex 逐一查看每個區塊的寫入器,並在每個中繼資料寫入器上叫用 IWICPersistStream.Save。

IWICMetadataWriter* piMetadataWRiter = NULL;
IWICPersistStream* piPersistStream = NULL;
HRESULT hr;

for (UINT x=0; x < m_blockCount; x++) 
{
    hr = GetWriterByIndex(x, & piMetadataWriter);
hr = piMetadataWriter->QueryInterface(
IID_IWICPersistStream,(void**)&piPersistStream);

hr = piPersistStream->Save(m_piStream, 
WICPersistOptions.WicPersistOptionDefault, 
true);
...
}

SetPalette

只有具有索引格式的編解碼器需要實作 SetPalette 方法。 如果影像使用索引格式,請使用此方法來指定影像中使用的色彩調色盤。 如果您的編解碼器沒有索引格式,請從此方法傳回WINCODEC_ERR_PALETTEUNAVAILABLE。

概念

實作 IWICBitmapCodecProgressNotification (Encoder)

實作 IWICMetadataBlockWriter

如何撰寫WIC-Enabled CODEC

Windows 映像元件概觀