IWICMetadataBlockReader implementeren
IWICMetadataBlockReader
Er bestaan vaak meerdere metagegevensblokken in een afbeelding, waarbij verschillende typen informatie in verschillende indelingen worden weergegeven. In het WIC-model (Windows Imaging Component) zijn metagegevenshandlers afzonderlijke onderdelen die, zoals decoders, tijdens runtime kunnen worden gedetecteerd. Elke metagegevensindeling heeft een aparte handler en elk van deze handlers kan worden gebruikt met elke afbeeldingsindeling die de betreffende metagegevensindeling ondersteunt. Als uw afbeeldingsindeling ondersteuning biedt voor EXIF, XMP, IPTC of een andere indeling, kunt u profiteren van de standaardmetagegevenshandlers voor deze indelingen die met WIC worden verzonden en u hoeft niet uw eigen indeling te schrijven. Als u natuurlijk een nieuwe indeling voor metagegevens maakt, moet u er een metagegevenshandler voor schrijven, die tijdens runtime wordt gedetecteerd en aangeroepen, net zoals de standaardindelingen zijn.
Notitie
Als uw afbeeldingsindeling is gebaseerd op een TIFF-container (Tagged Image File Format), hoeft u geen metagegevenshandlers te schrijven (tenzij u een nieuwe of eigen metagegevensindeling ontwikkelt). In TIFF- en JPEG-containers bevinden blokken metagegevens zich binnen IFD's en elke container heeft een andere IFD-structuur. WIC biedt IFD-handlers voor beide containerindelingen die door de IFD-structuur navigeren en delegeren naar de standaardmetagegevenshandlers om toegang te krijgen tot de metagegevens hierin. Dus als uw afbeeldingsindeling is gebaseerd op een van deze containers, kunt u automatisch profiteren van de WIC IFD-handlers. Als u echter een eigen containerindeling hebt die een eigen unieke metagegevensstructuur op het hoogste niveau heeft, moet u een handler schrijven die door die structuur op het hoogste niveau kan navigeren en delegeren naar de juiste metagegevenshandlers, net zoals de IFD-handlers.)
Op dezelfde manier biedt WIC een abstractielaag voor toepassingen waarmee ze op dezelfde manier met alle afbeeldingsindelingen kunnen werken via een consistente set interfaces, biedt WIC een abstractielaag voor codecauteurs met betrekking tot metagegevensindelingen. Zoals eerder vermeld, hoeven codecauteurs doorgaans niet rechtstreeks te werken met de verschillende metagegevensindelingen die mogelijk aanwezig zijn in een afbeelding. Elke codecauteur is echter verantwoordelijk voor het opsommen van de blokken met metagegevens, zodat een geschikte metagegevenshandler kan worden gedetecteerd en geïnstantieerd voor elk blok.
U moet deze interface implementeren in uw coderingsklasse op frameniveau. Mogelijk moet u deze ook implementeren op uw decoderklasse op containerniveau als uw afbeeldingsindeling globale metagegevens beschikbaar maakt buiten afzonderlijke afbeeldingsframes.
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 is hetzelfde als de methode GetContainerFormat bij het implementeren van IWICBitmapDecoder.
GetCount
GetCount- retourneert het aantal metagegevensblokken op het hoogste niveau dat aan het frame is gekoppeld.
GetEnumerator
GetEnumerator- retourneert een enumerator die de aanroeper kan gebruiken om de metagegevensblokken in het frame op te sommen en hun metagegevens te lezen. Als u deze methode wilt implementeren, moet u een metagegevenslezer maken voor elk blok met metagegevens en een opsommingsobject implementeren dat de verzameling metagegevenslezers opsommen. Het opsommingsobject moet IEnumUnknown- implementeren, zodat u het kunt casten naar IEnumUnknown wanneer u het retourneert in de ppIEnumMetadata-parameter.
Wanneer u het opsommingsobject implementeert, kunt u alle metagegevenslezers maken wanneer u voor het eerst het IWICMetadataBlockReader-object maakt of wanneer u het opsommingsobject voor het eerst maakt, of u kunt ze op een luie manier binnen de implementatie van de methode IEnumUnknown::Next maken. In veel gevallen is het efficiënter om ze lui aan te maken, maar in het volgende voorbeeld worden de bloklezers allemaal aangemaakt in de constructor om geheugen te besparen.
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
...
}
Als u de metagegevenslezers wilt maken, gebruikt u de methode CreateMetadataReaderFromContainer. Wanneer u deze methode aanroept, geeft u de GUID van de containerindeling door in de parameter guidContainerFormat. Als u een voorkeur van leverancier voor een metagegevenslezer hebt, kunt u de GUID van uw voorkeursleverancier doorgeven in de parameter pGuidVendor. Als uw bedrijf bijvoorbeeld metagegevenshandlers schrijft en u uw eigen indien aanwezig wilt gebruiken, kunt u de GUID van uw leverancier doorgeven. In de meeste gevallen geeft u alleen NULL-door en laat het systeem de juiste metagegevenslezer selecteren. Als u een specifieke leverancier aanvraagt en die leverancier wel een metagegevenslezer op de computer heeft geïnstalleerd, retourneert WIC de lezer van die leverancier. Als de aangevraagde leverancier echter geen metagegevenslezer op de computer heeft geïnstalleerd en als er een geschikte metagegevenslezer beschikbaar is, wordt die lezer geretourneerd, ook al is deze niet van de voorkeursleverancier. Als er geen metagegevenslezer op de computer is voor het type metagegevens in het blok, retourneert de componentenfabriek de onbekende metadata-handler, waarmee het blok metagegevens wordt behandeld als een binair groot object (BLOB) en wordt het blok met metagegevens uit het bestand gedeserialiseerd zonder te proberen het te parseren.
Voer voor de parameter dwOptions een OR-bewerking uit tussen de juiste WICPersistOptions- met de juiste WICMetadataCreationOptions-. De WICPersistOptions beschrijven hoe uw container is ingedeeld. Little Endian is de standaardinstelling.
enum WICPersistOptions
{
WICPersistOptionDefault,
WICPersistOptionLittleEndian,
WICPersistOptionBigEndian,
WICPersistOptionStrictFormat,
WICPersistOptionNoCacheStream,
WICPersistOptionPreferUTF8
};
De WICMetadataCreationOptions- geven aan of u de UnknownMetadataHandler wilt terughalen als er geen metagegevenslezer beschikbaar is op de computer die het metagegevensformaat van een bepaald blok kan lezen. WICMetadataCreationAllowUnknown is de standaard, en dient u altijd toe te staan dat de UnknownMetadataHandler wordt gemaakt. UnknownMetadataHandler behandelt niet-herkende metagegevens als een BLOB. Het kan deze niet parseren, maar schrijft deze als blob naar de stream en blijft intact wanneer deze tijdens het coderen naar de stream wordt teruggeschreven. Hierdoor is het veilig om metagegevenshandlers te maken voor propriëtaire metagegevens of metagegevensformaten die niet met het systeem worden meegeleverd. Omdat metagegevens intact blijven, zelfs als er geen handler aanwezig is op de computer die deze herkent, wanneer een geschikte metagegevenshandler later wordt geïnstalleerd, blijven de metagegevens aanwezig en kunnen ze worden gelezen. Als u het maken van de UnknownMetadataHandler niet toestaat, worden niet-herkende metagegevens genegeerd of overschreven. Dit is een vorm van gegevensverlies.
Notitie
Als u uw eigen metagegevenshandler schrijft voor eigen metagegevens, moet u nooit verwijzingen naar iets buiten het metagegevensblok zelf opnemen. Hoewel de UnknownMetadataHandler metagegevens intact bewaart, worden metagegevens verplaatst wanneer bestanden worden bewerkt en zijn verwijzingen naar iets buiten het eigen blok niet meer geldig wanneer dit gebeurt.
enum WICMetadataCreationOptions
{
WICMetadataCreationDefault = 0x00000000,
WICMetadataCreationAllowUnknown = WICMetadataCreationDefault,
WICMetadataCreationFailUnknown = 0x00010000,
WICMetadataCreationMask = 0xFFFF0000
};
De parameter pIStream is de werkelijke stroom die u decodeert. Voordat u de stroom doorgeeft, moet u naar het begin van het metagegevensblok gaan waarvoor u een lezer aanvraagt. De juiste metagegevenslezer voor het metagegevensblok bevindt zich op de huidige positie in de IStream en wordt geretourneerd in de parameter ppiReader.
GetReaderByIndex
GetReaderByIndex retourneert de metagegevenslezer op de gevraagde index in de verzameling.
Verwante onderwerpen
-
Referentie
-
Conceptuele
-
Hoe een WIC-Enabled CODEC te schrijven
-
Overzicht van Windows Imaging-onderdelen