Implementazione di IWICMetadataBlockReader

IWICMetadataBlockReader

All'interno di un'immagine esistono spesso più blocchi di metadati, ognuno dei quali espone diversi tipi di informazioni in formati diversi. Nel modello Windows Imaging Component (WIC) i gestori di metadati sono componenti distinti che, come i decodificatori, sono individuabili in fase di esecuzione. Ogni formato di metadati ha un gestore separato e ognuno di questi gestori di metadati può essere usato con qualsiasi formato di immagine che supporti il formato dei metadati gestito. Pertanto, se il formato di immagine supporta EXIF, XMP, IPTC o un altro formato, è possibile sfruttare i gestori di metadati standard per questi formati forniti con WIC e non è necessario scrivere i propri. Naturalmente, se si crea un nuovo formato di metadati, è necessario scrivere un gestore di metadati per esso, che verrà individuato e richiamato in fase di esecuzione proprio come quelli standard.

Nota

Se il formato dell'immagine è basato su un contenitore TIFF (Tagged Image File Format) o JPEG, non sarà necessario scrivere gestori di metadati (a meno che non si sviluppi un formato di metadati nuovo o proprietario). Nei contenitori TIFF e JPEG, i blocchi di metadati si trovano all'interno degli IFD e ogni contenitore ha una struttura IFD diversa. WIC fornisce gestori IFD per entrambi questi formati di contenitore che esplorano la struttura IFD e delegano ai gestori di metadati standard per accedere ai metadati all'interno di essi. Pertanto, se il formato dell'immagine è basato su uno di questi contenitori, è possibile sfruttare automaticamente i gestori IFD wic. Tuttavia, se si dispone di un formato di contenitore proprietario con una propria struttura di metadati di primo livello univoca, è necessario scrivere un gestore in grado di esplorare tale struttura di primo livello e delegare ai gestori di metadati appropriati, proprio come fanno i gestori IFD.

 

Lo stesso modo in cui WIC fornisce un livello di astrazione per le applicazioni che consente loro di lavorare con tutti i formati di immagine nello stesso modo tramite un set coerente di interfacce, WIC fornisce un livello di astrazione per gli autori di codec in relazione ai formati di metadati. Come indicato in precedenza, gli autori di codec in genere non devono lavorare direttamente con i vari formati di metadati che possono essere presenti in un'immagine. Tuttavia, ogni autore di codec è responsabile di fornire un modo per enumerare i blocchi di metadati in modo che un gestore di metadati appropriato possa essere individuato e creato un'istanza per ogni blocco.

È necessario implementare questa interfaccia nella classe di decodifica a livello di frame. Potrebbe anche essere necessario implementarlo nella classe decodificatore a livello di contenitore se il formato dell'immagine espone metadati globali all'esterno di singoli fotogrammi di immagine.

interface IWICMetadataBlockReader : IUnknown
{
   // All methods required
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetCount ( UINT *pcCount );
   HRESULT GetEnumerator ( IEnumUnknown **ppIEnumMetadata );
   HRESULT GetReaderByIndex ( UINT nIndex, IWICMetadataReader **ppIMetadataReader );
}

GetContainerFormat

GetContainerFormat equivale al metodo GetContainerFormat in Implementazione di IWICBitmapDecoder.

GetCount

GetCount restituisce il numero di blocchi di metadati di primo livello associati al frame.

GetEnumerator

GetEnumerator restituisce un enumeratore che il chiamante può usare per enumerare i blocchi di metadati nel frame e leggere i relativi metadati. Per implementare questo metodo, è necessario creare un lettore di metadati per ogni blocco di metadati e implementare un oggetto di enumerazione che enumera la raccolta di lettori di metadati. L'oggetto di enumerazione deve implementare IEnumUnknown in modo che sia possibile eseguirne il cast a IEnumUnknown quando viene restituito nel parametro ppIEnumMetadata .

Quando si implementa l'oggetto enumerazione, è possibile creare tutti i lettori di metadati quando si crea per la prima volta l'oggetto IWICMetadataBlockReader o quando si crea l'oggetto di enumerazione oppure è possibile crearli in modo differito all'interno dell'implementazione del metodo IEnumUnknown::Next . In molti casi, è più efficiente crearli in modo differitivo, ma, nell'esempio seguente, tutti i lettori di blocchi vengono creati nel costruttore per risparmiare spazio.

public class MetadataReaderEnumerator : public IEnumUnknown
{
   UINT m_current;
   UINT m_blockCount;
   IWICMetadataReader** m_ppMetadataReader;
   IStream* m_pStream;

   MetadataReaderEnumerator() 
   {
       // Set m_blockCount to the number of metadata blocks in the frame. 
      ...
      m_ppMetadataReader = IWICMetadataReader*[m_blockCount];
       m_current = 0;

      for (UINT x=0; x < m_blockCount; x++) 
      {
         // Find the position in the file where the xth
         // block of metadata lives and seek m_piStream 
         // to that position.
         ...

         m_pComponentFactory->CreateMetadataReaderFromContainer(
            GUID_ContainerFormatTiff,
                        NULL,
                        WICPersistOptions.WICPersistOptionsDefault | 
            WICMetadataCreationOptions.WICMetadataCreationDefault, 
                        m_pStream, &m_ppMetadataReader[x]);
        }
    }

    // Implementation of IEnumUnknown and IUnknown interfaces
    ...
}

Per creare i lettori di metadati, usare il metodo CreateMetadataReaderFromContainer . Quando si richiama questo metodo, si passa il GUID del formato del contenitore nel parametro guidContainerFormat . Se si ha una preferenza di fornitore per un lettore di metadati, è possibile passare il GUID del fornitore preferito nel parametro pGuidVendor . Ad esempio, se l'azienda scrive gestori di metadati e si vuole usare il proprio, se presente, è possibile passare il GUID del fornitore. Nella maggior parte dei casi, è sufficiente passare NULL e consentire al sistema di selezionare il lettore di metadati appropriato. Se si richiede un fornitore specifico e tale fornitore dispone di un lettore di metadati installato nel computer, WIC restituirà il lettore del fornitore. Tuttavia, se il fornitore richiesto non dispone di un lettore di metadati installato nel computer e, se è disponibile un lettore di metadati appropriato, tale lettore verrà restituito anche se non proviene dal fornitore preferito. Se nel computer non è presente alcun lettore di metadati per il tipo di metadati nel blocco, la factory dei componenti restituirà il gestore metadati sconosciuto, che considererà il blocco di metadati come un oggetto binario di grandi dimensioni (BLOB) e deserializzerà il blocco di metadati dal file senza alcun tentativo di analizzarlo.

Per il parametro dwOptions , eseguire un'operazione OR tra l'opzione WICPersistOptions appropriata con l'opzione WICMetadataCreationOptions appropriata. WiCPersistOptions descrive come viene disposto il contenitore. Little-endian è l'impostazione predefinita.

enum WICPersistOptions
{   
   WICPersistOptionDefault,
   WICPersistOptionLittleEndian,
   WICPersistOptionBigEndian,
   WICPersistOptionStrictFormat,
   WICPersistOptionNoCacheStream,
   WICPersistOptionPreferUTF8
};

WiCMetadataCreationOptions specifica se si desidera ripristinare UnknownMetadataHandler se nel computer non viene trovato alcun lettore di metadati in grado di leggere il formato dei metadati di un blocco specifico. WICMetadataCreationAllowUnknown è l'impostazione predefinita ed è sempre consigliabile consentire la creazione di UnknownMetadtataHandler. UnknownMetadataHandler considera i metadati non riconosciuti come BLOB. Non può analizzarlo, ma lo scrive nel flusso come BLOB e lo mantiene intatto quando viene riscritto nel flusso durante la codifica. In questo modo è possibile creare gestori di metadati per i metadati proprietari o i formati di metadati che non vengono forniti con il sistema. Poiché i metadati vengono mantenuti intatti, anche se nel computer non è presente alcun gestore che lo riconosce, quando un gestore di metadati appropriato viene installato in un secondo momento, i metadati saranno ancora presenti e potranno essere letti. Se non si consente la creazione di UnknownMetadataHandler, l'alternativa consiste nell'eliminare o sovrascrivere i metadati non riconosciuti. Si tratta di una forma di perdita di dati.

Nota

Se si scrive il proprio gestore di metadati per i metadati proprietari, non è mai consigliabile includere riferimenti a qualsiasi elemento esterno al blocco di metadati stesso. Anche se UnknownMetadataHandler mantiene intatti i metadati, i metadati vengono spostati quando vengono modificati i file e tutti i riferimenti a qualsiasi elemento esterno al proprio blocco non saranno più validi in questo caso.

 

enum WICMetadataCreationOptions
{
   WICMetadataCreationDefault = 0x00000000,
   WICMetadataCreationAllowUnknown = WICMetadataCreationDefault,
   WICMetadataCreationFailUnknown = 0x00010000,
   WICMetadataCreationMask = 0xFFFF0000
};

Il parametro pIStream è il flusso effettivo che si sta decodificando. Prima di passare il flusso, è necessario cercare all'inizio del blocco di metadati per il quale si richiede un lettore. Il lettore di metadati appropriato per il blocco di metadati nella posizione corrente in IStream verrà restituito nel parametro ppiReader .

GetReaderByIndex

GetReaderByIndex restituisce il lettore di metadati in corrispondenza dell'indice richiesto nella raccolta.

Riferimento

IWICMetadataBlockReader

Informazioni concettuali

Implementazione di IWICBitmapFrameDecode

Implementazione di IWICBitmapSourceTransform

Come scrivere un codec WIC-Enabled

Panoramica del componente Windows Imaging