Implementazione di IWICBitmapEncoder

IWICBitmapEncoder

Questa interfaccia è la controparte dell'interfaccia IWICBitmapDecoder ed è il punto di partenza per la codifica di un file di immagine. Proprio come IWICBitmapDecoder viene usato per recuperare le proprietà a livello di contenitore e i singoli fotogrammi dal contenitore di immagini, viene usato IWICBitmapEncoder per impostare le proprietà a livello di contenitore e serializzare singoli fotogrammi di immagine nel contenitore. Questa interfaccia viene implementata nella classe codificatore a livello di contenitore.

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);
};

Come illustrato in Implementazione di IWICBitmapDecoder, alcuni formati di immagine hanno anteprime globali, contesti di colore o metadati, mentre molti formati di immagine forniscono questi solo per fotogramma. Pertanto, i metodi per l'impostazione sono facoltativi in IWICBitmapEncoder, ma sono necessari in IWICBitmapFrameEncode. Verranno illustrati i metodi facoltativi su IWICBitmapEncoder nella sezione IWICBitmapFrameEncode, dove vengono implementati più comunemente.

Se non si supportano le anteprime globali, restituire WINCODEC_ERR_CODECNOTHUMBNAIL dal metodo SetThumbnail in IWICBitmapEncoder. Se non si supporta una tavolozza a livello di contenitore o se l'immagine che si sta codifica non ha un formato indicizzato, restituire WINCODEC_ERR_PALETTEUNAVAILABLE dal metodo SetPalette. Per qualsiasi altro metodo non supportato, restituire WINCODEC_ERR_UNSUPPORTEDOPERATION.

Initialize

Initialize è il primo metodo richiamato in un IWICBitmapEncoder dopo che è stata creata un'istanza. Un flusso di immagini viene passato al codificatore e un chiamante può facoltativamente specificare un'opzione cache. Nel caso del decodificatore, il flusso è di sola lettura, ma il flusso passato a un codificatore è un flusso scrivibile, in cui il codificatore serializzerà tutti i dati e i metadati dell'immagine. Le opzioni della cache nel codificatore sono diverse.

enum WICBitmapEncoderCacheOption
{
   WICBitmapEncoderCacheInMemory,
   WICBitmapEncoderCacheTempFile,
   WICBitmapEncoderNoCache
}

L'applicazione ha una scelta di richiedere al codificatore di memorizzare nella cache i dati dell'immagine in memoria, memorizzarla nella cache in un file temporaneo o di scriverla direttamente nel file del disco senza memorizzazione nella cache. Quando viene chiesto di memorizzare nella cache i dati in un file temporaneo, il codificatore deve creare un file temporaneo su disco e scrivere direttamente in tale file senza memorizzare nella cache nella memoria. Quando il chiamante seleziona l'opzione nessuna cache, ogni frame deve essere eseguito il commit per poter creare il frame successivo.

GetContainerFormat

GetContainerFormat viene implementato allo stesso modo del metodo GetContainerFormatnell'implementazione di IWICBitmapDecoder.

GetEncoderInfo

GetEncoderInfo restituisce un oggetto IWICBitmapEncoderInfo . Per ottenere l'oggetto IWICBitmapEncoderInfo , passare il GUID del codificatore al metodo CreateComponentInfo in IWICImagingFactory e quindi richiedere l'interfaccia IWICBitmapEncoderInfo .

Vedere l'esempio in Implementazione di IWICBitmapDecoder in GetDecoderInfo.

CreateNewFrame

CreateNewFrame è la controparte del codificatore di GetFrame in IWICBitmapDecoder. Questo metodo restituisce un oggetto IWICBitmapFrameEncode , ovvero l'oggetto che serializza effettivamente i dati dell'immagine per un frame specifico all'interno del contenitore.

Uno dei vantaggi di Windows Imaging Component (WIC) è che fornisce un livello di astrazione per le applicazioni che consente loro di lavorare con tutti i formati di immagine nello stesso modo. Tuttavia, non tutti i formati di immagine sono esattamente uguali. Alcuni formati di immagine hanno funzionalità che altri non hanno. Per consentire alle applicazioni di sfruttare queste funzionalità univoche, è necessario fornire un modo per esporre il codec. Questo è lo scopo delle opzioni del codificatore. Se il codec supporta qualsiasi opzione del codificatore, è necessario creare un oggetto IPropertyBag2 che espone le opzioni del codificatore supportate e restituirlo nel parametro ppIEncoderOptions di questo metodo. Il chiamante può quindi usare questo oggetto IPropertyBag2 per determinare le opzioni del codificatore supportate dal codec. Se il chiamante vuole specificare i valori per una delle opzioni del codificatore supportate, assegna il valore alla proprietà pertinente nell'oggetto IPropertyBag2 e lo passa all'oggetto IWICBitmapFrameEncode appena creato nel relativo metodo Initialize.

Per creare un'istanza di un oggetto IPropertyBag2 , è prima necessario creare uno struct PROPBAG2 per specificare ogni opzione codificatore supportata dal codificatore e il relativo tipo di dati per ogni proprietà. È quindi necessario implementare un oggetto IPropertyBag2 che applica gli intervalli di valori per ogni proprietà in scrittura e riconcilia eventuali valori in conflitto o sovrapposti. Per set semplici di opzioni di codificatore non in conflitto, è possibile richiamare il metodo CreateEncoderPropertyBag , che creerà un semplice oggetto IPropertyBag2 usando le proprietà specificate nello struct PROPBAG2. È comunque necessario applicare gli intervalli di valori. Per opzioni di codificatore più avanzate o se è necessario riconciliare i valori in conflitto, è necessario scrivere la propria implementazione 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 offre un piccolo set di opzioni di codificatore canoniche usate da alcuni dei formati di immagine comuni. Tutte le opzioni del codificatore canonico sono facoltative e i codec non sono necessari per supportarli. Il motivo per cui vengono fornite come opzioni canoniche è perché molte applicazioni espongono l'interfaccia utente per gli utenti per specificare queste opzioni quando si salva un file di immagine in un formato che li supporta. Fornendo un modo canonico per specificare queste opzioni, le applicazioni possono comunicare facilmente ai codificatori in modo coerente. Le opzioni del codificatore canonico sono elencate nella tabella seguente.

Opzione codificatore VARTYPE Gamma valori
Lossless VT_BOOL Vero/Falso
ImageQuality VT_R4 0.0-1.0
CompressionQuality VT_R4 0.0-1.0
BitmapTransform VT_UI1 WICBitmapTransformOptions

 

Se il codec supporta la codifica senza perdita, è necessario esporre l'opzione codificatore Lossless come modo per le applicazioni per richiedere che un'immagine sia codificata senza perdita di dati. Se un chiamante imposta questa proprietà su True, è necessario ignorare l'opzione ImageQuality e codificare l'immagine senza perdita.

L'opzione ImageQuality consente a un'applicazione di specificare il grado di fedeltà con cui codificare l'immagine. Questa opzione consente a un utente di eseguire un compromesso tra la qualità dell'immagine e la velocità e/o le dimensioni del file. JPEG è un esempio di formato immagine che supporta questo compromesso. Un valore pari a 0.0 indica che la fedeltà è di bassa importanza e il codificatore deve usare il relativo algoritmo di perdita più elevato. Un valore 1.0 indica che la fedeltà è la più importante e il codificatore deve mantenere la massima fedeltà possibile. A seconda del codec, questo può essere sinonimo dell'opzione Lossless. Tuttavia, se il codec supporta la codifica senza perdita e se l'opzione Lossless è impostata su True, l'opzione ImageQuality deve essere ignorata.

L'opzione CompressionQuality consente a un'applicazione di specificare l'efficienza della compressione da usare durante la codifica dell'immagine. Un algoritmo molto efficiente può produrre un file di immagine più piccolo con la stessa qualità di un algoritmo di compressione meno efficiente, ma potrebbe richiedere più tempo per codificare. Questa opzione consente a un utente di specificare un compromesso tra le dimensioni dei file rispetto alla velocità di codifica, mantenendo lo stesso livello di qualità. TIFF è un esempio di formato immagine che supporta questo compromesso. Si noti che un formato, ad esempio JPEG, supporta livelli diversi di compressione, ma una maggiore frequenza di compressione comporta una qualità dell'immagine inferiore. Pertanto, un formato di immagine JPEG espone l'opzione ImageQuality anziché l'opzione CompressionQuality. Un valore pari a 0,0 per questa opzione indica che è necessario comprimere l'immagine il più rapidamente possibile, senza ridurre la fedeltà, a spese di una dimensione di file più grande. Un valore 1.0 indica che è necessario creare le dimensioni del file più piccole possibili (allo stesso livello di qualità), indipendentemente dal tempo necessario per codificarlo. Un codec può supportare sia l'opzione ImageQuality che l'opzione CompressionQuality, in cui l'opzione ImageQuality specifica il grado di perdita accettabile e l'opzione CompressionQuality offre un compromesso di dimensioni/velocità a livello di qualità specificato.

L'opzione BitmapTransform consente al chiamante di specificare un angolo di rotazione o un orientamento verticale o orizzontale quando si esegue la codifica. L'enumerazione WICBitmapTransformOptions utilizzata per specificare la trasformazione richiesta è la stessa enumerazione utilizzata durante la richiesta di una trasformazione durante la decodifica tramite l'interfaccia IWICBitmapSourceTransform.

Si noti che i codificatori non sono limitati alle opzioni del codificatore canonico. Lo scopo delle opzioni del codificatore è consentire ai codificatori di esporre le proprie funzionalità e non esiste alcun limite ai tipi di funzionalità che è possibile esporre. Assicurarsi che le opzioni del codificatore siano ben documentate. Anche se un'applicazione può usare il contenitore di proprietà restituito da questo metodo per individuare i nomi, i tipi e gli intervalli di valori per le opzioni supportate, l'unico modo per scoprirne i significati o come esponerli nell'interfaccia utente, è dalla documentazione.

Commit

Commit è il metodo chiamato dopo che tutti i dati e i metadati dell'immagine sono stati serializzati nel flusso. È consigliabile usare questo metodo per serializzare i dati dell'immagine di anteprima nel flusso ed eventuali anteprime globali, metadati, tavolozza o altri elementi, se applicabile. Questo metodo non deve chiudere il flusso di file, perché è previsto che l'applicazione che ha aperto il flusso lo chiuda.

La sezione del metodo IWICBitmapFrameEncode:Commit contiene informazioni dettagliate su come IWICBitmapEncoderCacheOptions influisce sul comportamento di questo metodo.

SetPreview

SetPreview viene usato per creare un'anteprima dell'immagine. Anche se non è strettamente necessario che ogni immagine abbia un'anteprima, è consigliabile. Le moderne fotocamere digitali e scanner generano immagini ad alta risoluzione, che tendono a essere molto grandi e, di conseguenza, richiedono tempi di elaborazione significativi per decodificare. Le immagini della prossima generazione di fotocamere saranno ancora più grandi. È consigliabile fornire una versione con risoluzione inferiore e più piccola di un'immagine, in genere in formato JPEG, che può essere decodificata e visualizzata rapidamente "immediatamente" quando un utente lo richiede. Un'applicazione può richiedere un'anteprima prima di richiedere la decodifica dell'immagine effettiva per offrire un'esperienza migliore per gli utenti e mostrare loro una rappresentazione delle dimensioni dello schermo dell'immagine mentre sono in attesa di decodificare l'immagine effettiva. Anche se i codec devono fornire anteprime, i codec che non supportano IWICBitmapSourceTransform dovrebbero sicuramente farlo.

Se si fornisce un'anteprima JPEG, non è necessario scrivere un codificatore JPEG per codificarlo. È necessario delegare al codificatore JPEG fornito con la piattaforma WIC per la codifica delle anteprime e delle anteprime.

Riferimento

IWICBitmapEncoder

IWICBitmapFrameEncode

Informazioni concettuali

Interfacce del codificatore

Implementazione di IWICBitmapCodecProgressNotification (codificatore)

Come scrivere un codec WIC-Enabled

Panoramica del componente Windows Imaging