Delen via


Overzicht van metagegevens van lezen en schrijven van afbeeldingen

In dit onderwerp vindt u een overzicht van hoe u de WIC-API's (Windows Imaging Component) kunt gebruiken voor het lezen en schrijven van metagegevens die zijn ingesloten in afbeeldingsbestanden.

Dit onderwerp bevat de volgende secties.

Voorwaarden

Als u dit onderwerp wilt begrijpen, moet u bekend zijn met het WIC-metagegevenssysteem, zoals beschreven in het OVERZICHT van WIC-metagegevens. U moet ook bekend zijn met de querytaal die wordt gebruikt voor het lezen en schrijven van metagegevens, zoals beschreven in Overzicht van metagegevensquerytaal.

Introductie

WIC biedt toepassingsontwikkelaars com-onderdelen (Component Object Model) voor het lezen en schrijven van metagegevens die zijn ingesloten in afbeeldingsbestanden. Er zijn twee manieren om metagegevens te lezen en te schrijven:

  • Een querylezer/schrijver en een query-expressie gebruiken om metagegevensblokken op te vragen voor geneste blokken of specifieke metagegevens binnen een blok.
  • Met behulp van een metagegevenshandler (een metagegevenslezer of een metagegevensschrijver) om toegang te krijgen tot de geneste metagegevensblokken of specifieke metagegevens in de metagegevensblokken.

De eenvoudigste hiervan is het gebruik van een querylezer/schrijver en een query-expressie voor toegang tot de metagegevens. Een querylezer (IWICMetadataQueryReader) wordt gebruikt om metagegevens te lezen terwijl een queryschrijver (IWICMetadataQueryWriter) wordt gebruikt om metagegevens te schrijven. Beide gebruiken een query-expressie om de gewenste metagegevens te lezen of te schrijven. Achter de schermen gebruikt een querylezer (en schrijver) een metagegevenshandler voor toegang tot de metagegevens die door de query-expressie worden beschreven.

De meer geavanceerde methode is om rechtstreeks toegang te krijgen tot de metagegevenshandlers. Een metagegevenshandler wordt verkregen uit de afzonderlijke frames met behulp van een bloklezer (IWICMetadataBlockReader) of een blokschrijver (IWICMetadataBlockWriter). De twee typen metagegevenshandlers zijn de metagegevenslezer (IWICMetadataReader) en de metagegevensschrijver (IWICMetadataWriter).

Het volgende diagram van de inhoud van een JPEG-afbeeldingsbestand wordt gebruikt in de voorbeelden in dit onderwerp. De afbeelding die wordt vertegenwoordigd door dit diagram is gemaakt met Behulp van Microsoft Paint; de metagegevens van de classificatie zijn toegevoegd met behulp van de functie Photo Gallery van Windows Vista.

illustratie van jpeg-afbeelding met beoordelingsmetagegevens

Metadadata lezen met behulp van een querylezer

De eenvoudigste manier om metagegevens te lezen is door de interface van de querylezer te gebruiken, IWICMetadataQueryReader. Met de querylezer kunt u metagegevensblokken en items in metagegevensblokken lezen met behulp van een query-expressie.

Er zijn drie manieren om een querylezer te verkrijgen: via een bitmapdecoder (IWICBitmapDecoder), via de afzonderlijke frames (IWICBitmapFrameDecode) of via een queryschrijver (IWICMetadataQueryWriter).

Een querylezer verkrijgen

In de volgende voorbeeldcode ziet u hoe u een bitmapdecode ophaalt uit de imaging factory en een afzonderlijk bitmapframe ophaalt. Met deze code wordt ook het installatiewerk uitgevoerd dat nodig is om een querylezer op te halen uit een gedecodeerd frame.

IWICImagingFactory *pFactory = NULL;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pFrameDecode = NULL;
IWICMetadataQueryReader *pQueryReader = NULL;
IWICMetadataQueryReader *pEmbedReader = NULL;
PROPVARIANT value;

// Initialize COM
CoInitialize(NULL);

// Initialize PROPVARIANT
PropVariantInit(&value);

//Create the COM imaging factory
HRESULT hr = CoCreateInstance(
    CLSID_WICImagingFactory,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IWICImagingFactory,
    (LPVOID*)&pFactory);

// Create the decoder
if (SUCCEEDED(hr))
{
    hr = pFactory->CreateDecoderFromFilename(
        L"test.jpg",
        NULL,
        GENERIC_READ,
        WICDecodeMetadataCacheOnDemand,
        &pDecoder);
}

// Get a single frame from the image
if (SUCCEEDED(hr))
{
    hr = pDecoder->GetFrame(
         0,  //JPEG has only one frame.
         &pFrameDecode); 
}

De bitmapdecoder voor het bestand test.jpg wordt verkregen met behulp van de CreateDecoderFromFilename methode van de imaging factory. In deze methode wordt de vierde parameter ingesteld op de waarde WICDecodeMetadataCacheOnDemand uit de opsomming WICDecodeOptions. Dit vertelt de decoder dat de metagegevens in de cache moeten worden opgeslagen wanneer ze nodig zijn, hetzij door een querylezer of de onderliggende metagegevenslezer te verkrijgen. Met deze optie kunt u de stroom behouden naar de metagegevens die vereist zijn voor snelle codering van metagegevens en maakt verliesloze decodering van de JPEG-afbeelding mogelijk. U kunt ook de andere WICDecodeOptions waarde, WICDecodeMetadataCacheOnLoad, gebruiken, waarmee de ingesloten afbeeldingsmetagegevens in de cache worden opgeslagen zodra de afbeelding is geladen.

Als u de querylezer van het frame wilt verkrijgen, maakt u een eenvoudige aanroep naar de GetMetadataQueryReader methode. De volgende code demonstreert deze aanroep.

// Get the query reader
if (SUCCEEDED(hr))
{
    hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}

Op dezelfde manier kan een querylezer ook worden verkregen op decoderniveau. Een eenvoudige aanroep van de decoder GetMetadataQueryReader methode haalt de querylezer van de decoder op. De querylezer van een decoder leest, in tegenstelling tot de querylezer van een frame, metagegevens voor een afbeelding die zich buiten de afzonderlijke frames bevindt. Dit scenario is echter niet gebruikelijk en de systeemeigen afbeeldingsindelingen bieden geen ondersteuning voor deze mogelijkheid. De native codecs voor afbeeldingen van WIC lezen en schrijven metadata op frameniveau, zelfs voor formaten met één frame, zoals JPEG.

Metagegevens lezen

Voordat u verdergaat met het lezen van metagegevens, bekijkt u het volgende diagram van een JPEG-bestand met ingesloten metagegevensblokken en werkelijke gegevens om op te halen. Dit diagram bevat aanduidingen voor specifieke metagegevensblokken en items in de afbeelding, die de metagegevensqueryexpressie aan elk blok of item verlenen.

illustratie van een jpeg-bestand met metadata-aanroepen

Als u een query wilt uitvoeren op ingesloten metagegevensblokken of specifieke items op naam, roept u de methode GetMetadataByName aan. Deze methode accepteert een queryexpressie en een PROPVARIANT- waarin het metagegevens-item wordt geretourneerd. De volgende code voert een query uit voor een genest metadatablok en zet de IUnknown-component, geleverd door de PROPVARIANT-waarde, om in een querylezer indien deze wordt gevonden.

if (SUCCEEDED(hr))
{
    // Get the nested IFD reader
    hr = pQueryReader->GetMetadataByName(L"/app1/ifd", &value);
    if (value.vt == VT_UNKNOWN)
    {
        hr = value.punkVal->QueryInterface(IID_IWICMetadataQueryReader, (void **)&pEmbedReader);
    }
    PropVariantClear(&value); // Clear value for new query
}

De queryexpressie '/app1/ifd' voert een query uit op het IFD-blok dat is genest in het app1-blok. Het JPEG-afbeeldingsbestand bevat het geneste metagegevensblok IFD, dus de PROPVARIANT- wordt geretourneerd met een variabel type (vt) van VT_UNKNOWN en een aanwijzer naar een IUnknown interface (punkVal). Vervolgens voert u een query uit op de IUnknown-interface voor een querylezer.

De volgende code demonstreert een nieuwe query op basis van de nieuwe query-lezer ten opzichte van het geneste IFD-blok.

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetMetadataByName(L"/{ushort=18249}", &value);
    PropVariantClear(&value); // Clear value for new query
}

De queryexpressie "/{ushort=18249}" voert een query uit op het IFD-blok voor de MicrosoftPhoto-waardering die is ingebed onder tag 18249. De PROPVARIANT- waarde bevat nu een waardetype van VT_UI2 en een gegevenswaarde van 50.

Het is echter niet nodig om een genest blok te verkrijgen voordat u een query uitvoert voor specifieke gegevenswaarden. In plaats van bijvoorbeeld een query uit te voeren op de geneste IFD en vervolgens voor de MicrosoftPhoto-classificatie, kunt u in plaats daarvan het basismetagegevensblok en de query gebruiken die in de volgende code wordt weergegeven om dezelfde informatie te verkrijgen.

if (SUCCEEDED(hr))
{
    hr = pQueryReader->GetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);
    PropVariantClear(&value);
}

Naast het opvragen van specifieke metagegevensitems in een metagegevensblok, kunt u ook alle metagegevensitems in een metagegevensblok opsommen (niet inclusief metagegevensitems in geneste metagegevensblokken). Om de metagegevensitems in het huidige blok op te sommen, wordt de GetEnumeration-methode van de query-lezer gebruikt. Met deze methode wordt een IEnumString-interface ingevuld met de metagegevensitems uit het huidige blok. Met de volgende code wordt bijvoorbeeld de XMP-classificatie en MicrosoftPhoto-classificatie opgesomd voor het geneste IFD-blok dat eerder is verkregen.

IEnumString *metadataItems = NULL;

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetEnumerator(&metadataItems);
}

Voor meer informatie over het identificeren van de juiste tags voor verschillende afbeeldingsindelingen en metagegevensindelingen, zie Metagegevensquery's voor native afbeeldingsformaten.

Aanvullende methoden voor querylezers

Naast het lezen van metagegevens kunt u ook aanvullende informatie over de querylezer verkrijgen en metagegevens op andere manieren verkrijgen. De querylezer biedt twee methoden voor informatie over de querylezer, GetContainerFormat en GetLocation-.

Met de ingesloten querylezer kunt u GetContainerFormat gebruiken om het type metagegevensblok te bepalen en u kunt GetLocation- aanroepen om het pad te verkrijgen ten opzichte van het hoofdmetagegevensblok. Met de volgende code wordt de locatie van de ingesloten querylezer opgevraagd.

// Determine the metadata block format

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetContainerFormat(&containerGUID);
}

// Determine the query reader's location
if (SUCCEEDED(hr))
{
    UINT length;
    WCHAR readerNamespace[100];
    hr = pEmbedReader->GetLocation(100, readerNamespace, &length);
}

De aanroep van GetContainerFormat voor de ingesloten query-lezer retourneert de GUID voor de metagegevensindeling van de IFD. De aanroep van GetLocation retourneert een naamruimte van '/app1/ifd', waarmee u het relatieve pad krijgt van waaruit volgende query's naar de nieuwe querylezer worden uitgevoerd. De voorgaande code is natuurlijk niet erg nuttig, maar laat wel zien hoe u de methode GetLocation kunt gebruiken om geneste metagegevensblokken te vinden.

Metagegevens schrijven met behulp van een queryschrijver

Notitie

Sommige codevoorbeelden in deze sectie worden niet weergegeven in de context van de werkelijke stappen die nodig zijn om metagegevens te schrijven. Als u de codevoorbeelden in de context van een werkend voorbeeld wilt bekijken, raadpleegt u de zelfstudie 'Hoe: Een afbeelding opnieuw coderen met metadata'.

 

Het belangrijkste onderdeel voor het schrijven van metagegevens is de queryschrijver (IWICMetadataQueryWriter). Met de queryschrijver kunt u metagegevensblokken en items in een metagegevensblok instellen en verwijderen.

Net als de querylezer zijn er drie manieren om een queryschrijver te verkrijgen: via een bitmapcoderingsprogramma (IWICBitmapEncoder), via de afzonderlijke frames (IWICBitmapFrameEncode), of via een snelle metagegevenscoderingsprogramma (IWICFastMetadataEncoder).

Een queryschrijver verkrijgen

De meest voorkomende schrijver van queries is voor een individueel frame van een bitmap. Met deze queryschrijver worden de metagegevensblokken en items van een afbeeldingsframe ingesteld en verwijderd. Als u de queryschrijver van een afbeeldingsframe wilt verkrijgen, roept u de GetMetadataQueryWriter methode van het frame aan. De volgende code demonstreert de eenvoudige aanroep van een methode om de queryschrijver van een frame te verkrijgen.

IWICMetadataQueryWriter &pFrameQWriter = NULL;

//Obtain a query writer from the frame.
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);

Op dezelfde manier kan een query-schrijver ook worden verkregen voor het encoder-niveau. Een eenvoudige aanroep van de encoder GetMetadataQueryWriter methode haalt de queryschrijver van de encoder op. De queryschrijver van een encoder schrijft, in tegenstelling tot de queryschrijver van een frame, metagegevens voor een afbeelding buiten het afzonderlijke frame. Dit scenario is echter niet gebruikelijk en de systeemeigen afbeeldingsindelingen bieden geen ondersteuning voor deze mogelijkheid. De systeemeigen afbeeldingscodecs van WIC lezen en schrijven metagegevens op frameniveau, zelfs voor indelingen met één frame, zoals JPEG.

U kunt ook rechtstreeks een queryschrijver verkrijgen vanuit de imaging factory (IWICImagingFactory). Er zijn twee imaging factory-methoden die een queryschrijver retourneren: CreateQueryWriter en CreateQueryWriterFromReader.

CreateQueryWriter maakt een queryschrijver voor de opgegeven metagegevensindeling en leverancier. Met deze queryschrijver kunt u metagegevens schrijven voor een specifieke indeling voor metagegevens en deze toevoegen aan de afbeelding. De volgende code demonstreert een CreateQueryWriter aanroep om een XMP-queryschrijver te maken.

IWICMetadataQueryWriter *pXMPWriter = NULL;

// Create XMP block
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriter(
        GUID_MetadataFormatXMP,
        &vendor,
        &pXMPWriter);

In dit voorbeeld wordt de beschrijvende naam GUID_MetadataFormatXMP gebruikt als de guidMetadataFormat-parameter . Het vertegenwoordigt de GUID van de XMP-metagegevensindeling en de leverancier vertegenwoordigt de door Microsoft gemaakte handler. Als alternatief kan NULL- worden doorgegeven als de parameter pguidVendor met dezelfde resultaten als er geen andere XMP-handler bestaat. Als een aangepaste XMP-handler naast de systeemeigen XMP-handler wordt geïnstalleerd, leidt het doorgeven van NULL- voor de leverancier ertoe dat de queryschrijver de laagste GUID retourneert.

CreateQueryWriterFromReader is vergelijkbaar met de methode CreateQueryWriter, behalve dat de nieuwe queryschrijver vooraf wordt ingevuld met de gegevens die door de querylezer worden geleverd. Dit is handig voor het opnieuw coderen van een afbeelding terwijl de bestaande metagegevens behouden blijven, of voor het verwijderen van ongewenste metagegevens. De volgende code demonstreert een CreateQueryWriterFromReader aanroep.

hr = pFrameDecode->GetMetadataQueryReader(&pFrameQReader);

// Copy metadata using query readers
if(SUCCEEDED(hr) && pFrameQReader)
{
    IWICMetadataQueryWriter *pNewWriter = NULL;

    GUID vendor = GUID_VendorMicrosoft;
    hr = pFactory->CreateQueryWriterFromReader(
        pFrameQReader,
        &vendor,
        &pNewWriter);

Metagegevens toevoegen

Nadat u een queryschrijver hebt verkregen, kunt u deze gebruiken om metagegevensblokken en items toe te voegen. Als u metagegevens wilt schrijven, gebruikt u de methode SetMetadataByName van de queryschrijver. SetMetadataByName gebruikt twee parameters: een query-expressie (wzName) en een aanwijzer naar een PROPVARIANT (pvarValue). De queryexpressie definieert het blok of item dat moet worden ingesteld terwijl propvariant de werkelijke gegevenswaarde biedt die moet worden ingesteld.

In het volgende voorbeeld ziet u hoe u een titel toevoegt met behulp van de XMP-queryschrijver die u eerder hebt verkregen met behulp van de methode CreateQueryWriter.

// Write metadata to the XMP writer
if (SUCCEEDED(hr))
{
    PROPVARIANT value;
    PropVariantInit(&value);

    value.vt = VT_LPWSTR;
    value.pwszVal = L"Metadata Test Image.";
   
    hr = pXMPWriter->SetMetadataByName(L"/dc:title", &value);

    PropVariantClear(&value);
}

In dit voorbeeld is het type waarde (vt) ingesteld op VT_LPWSTR, waarmee wordt aangegeven dat een tekenreeks wordt gebruikt als de gegevenswaarde. Omdat waarde's type een tekenreeks is, wordt pwszVal- gebruikt om de titel in te stellen die moet worden gebruikt. SetMetadataByName wordt vervolgens aangeroepen met behulp van de queryexpressie "/dc:title" en de zojuist ingestelde PROPVARIANT-. De gebruikte query-expressie geeft aan dat de eigenschap 'titel' in het digitale cameraschema (dc) moet zijn ingesteld. Houd er rekening mee dat de expressie niet '/xmp/dc:title' is; dit komt omdat de queryschrijver al specifiek is voor XMP en geen ingesloten XMP-blok bevat, wat '/xmp/dc:title' zou voorstellen.

Tot nu toe hebt u nog geen metagegevens toegevoegd aan een afbeeldingskader. U hebt eenvoudig een query-opsteller met gegevens gevuld. Om aan een frame een metagegevensblok toe te voegen dat wordt vertegenwoordigd door de query writer, roept u nogmaals SetMetadataByName aan, waarbij u de query writer gebruikt als de waarde van de PROPVARIANT. Hiermee worden de metagegevens in de queryschrijver effectief gekopieerd naar het afbeeldingskader. De volgende code laat zien hoe u de metagegevens toevoegt in de XMP-queryschrijver die eerder is verkregen aan het hoofdmetagegevensblok van een frame.

// Get the frame's query writer and write the XMP query writer to it
if (SUCCEEDED(hr))
{
    hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);

    // Copy the metadata in the XMP query writer to the frame
    if (SUCCEEDED(hr))
    {
        PROPVARIANT value;

        PropVariantInit(&value);
        value.vt = VT_UNKNOWN;
        value.punkVal = pXMPWriter;
        value.punkVal->AddRef();

        hr = pFrameQWriter->SetMetadataByName(L"/", &value);

        PropVariantClear(&value);
    }
}

In dit voorbeeld wordt een waardetype (vt) van VT_UNKOWN gebruikt; een COM-interfacewaardetype aan te geven. De XMP-queryschrijver (piXMPWriter) wordt vervolgens gebruikt als waarde voor de PROPVARIANT, door er een verwijzing aan toe te voegen met behulp van de AddRef-methode. Ten slotte wordt de XMP-queryschrijver ingesteld door de SetMetadataByName-methode van het frame aan te roepen en de queryexpressie '/' door te geven, waarmee het hoofdblok wordt aangegeven en de zojuist ingestelde PROPVARIANT.

Notitie

Als het frame al het metagegevensblok bevat dat u wilt toevoegen, worden de metagegevens die u toevoegt toegevoegd en bestaande metagegevens overschreven.

 

Metagegevens verwijderen

Met een queryschrijver kunt u ook metagegevens verwijderen door de methode RemoveMetadataByName aan te roepen. RemoveMetadataByName een query-expressie gebruikt en het metagegevensblok of item verwijdert als dit bestaat. De volgende code laat zien hoe u de titel verwijdert die eerder is toegevoegd.

if (SUCCEEDED(hr))
{
    hr = pFrameQWriter->RemoveMetadataByName(L"/xmp/dc:title");
}

De volgende code laat zien hoe u het volledige XMP-metagegevensblok verwijdert.

if (SUCCEEDED(hr))
{
    hr = pFrameQWriter->RemoveMetadataByName(L"/xmp");
}

Metagegevens kopiëren voor opnieuw coderen

Notitie

De code in deze sectie is alleen geldig wanneer de bron- en doelafbeeldingsindelingen hetzelfde zijn. U kunt niet alle metagegevens van een afbeelding in één bewerking kopiëren bij het coderen naar een andere afbeeldingsindeling.

 

Als u metagegevens wilt behouden tijdens het opnieuw coderen van een afbeelding in dezelfde afbeeldingsindeling, zijn er methoden beschikbaar voor het kopiëren van alle metagegevens in één bewerking. Elk van deze bewerkingen volgt een vergelijkbaar patroon; elk stelt de metagegevens van het gedecodeerde frame rechtstreeks in het nieuwe frame dat wordt gecodeerd.

De voorkeursmethode voor het kopiëren van metagegevens is het initialiseren van de blokschrijver van het nieuwe frame met de gecodeerde bloklezer van het frame. De volgende code demonstreert deze methode.

if (SUCCEEDED(hr) && formatsEqual)
{
    // Copy metadata using metadata block reader/writer
    if (SUCCEEDED(hr))
    {
        pFrameDecode->QueryInterface(
            IID_IWICMetadataBlockReader,
            (void**)&pBlockReader);
    }
    if (SUCCEEDED(hr))
    {
        pFrameEncode->QueryInterface(
            IID_IWICMetadataBlockWriter,
            (void**)&pBlockWriter);
    }
    if (SUCCEEDED(hr))
    {
        pBlockWriter->InitializeFromBlockReader(pBlockReader);
    }
}

In dit voorbeeld worden de bloklezer en de blokschrijver respectievelijk verkregen uit het bronframe en het doelframe. De blokschrijver wordt vervolgens geïnitialiseerd vanuit de bloklezer. Hiermee initialiseert u de bloklezer met de vooraf ingevulde metagegevens van de bloklezer.

Een andere methode voor het kopiëren van metagegevens is het schrijven van het metagegevensblok waarnaar wordt verwezen door de querylezer met behulp van de queryschrijver van de encoder. De volgende code demonstreert deze methode.

if (SUCCEEDED(hr) && formatsEqual)
{
    hr = pFrameDecode->GetMetadataQueryReader(&pFrameQReader);

    // Copy metadata using query readers
    if(SUCCEEDED(hr))
    {
        hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
        if (SUCCEEDED(hr))
        {
            PropVariantClear(&value);
            value.vt=VT_UNKNOWN;
            value.punkVal=pFrameQReader;
            value.punkVal->AddRef();
            hr = pFrameQWriter->SetMetadataByName(L"/", &value);
            PropVariantClear(&value);
        }
    }
}

Hier wordt een querylezer opgehaald uit het gedecodeerde frame en vervolgens gebruikt als de eigenschapswaarde van de PROPVARIANT- met een waardetype ingesteld op VT_UNKNOWN. De queryschrijver voor de encoder wordt verkregen en de queryexpressie '/' wordt gebruikt om de metagegevens in te stellen op het hoofdnavigatiepad. U kunt deze methode ook gebruiken bij het instellen van geneste metagegevensblokken door de query-expressie aan te passen op de gewenste locatie.

Op dezelfde manier kunt u een queryschrijver maken op basis van de gedecodeerde querylezer van het frame met behulp van de methode CreateQueryWriterFromReader van de imaging factory. De queryschrijver die tijdens deze bewerking is gemaakt, wordt vooraf ingevuld met de metagegevens van de querylezer en kan daarna in het frame worden ingesteld. De volgende code demonstreert de CreateQueryWriterFromReader kopieerbewerking.

IWICMetadataQueryWriter *pNewWriter = NULL;

GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriterFromReader(
    pFrameQReader,
    &vendor,
    &pNewWriter);

if (SUCCEEDED(hr))
{
    // Get the frame's query writer
    hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
}

// Set the query writer to the frame.
if (SUCCEEDED(hr))
{
    PROPVARIANT value;

    PropVariantInit(&value);
    value.vt = VT_UNKNOWN;
    value.punkVal = pNewWriter;
    value.punkVal->AddRef();
    hr = pFrameQWriter->SetMetadataByName(L"/",&value);
}

Deze methode maakt gebruik van een afzonderlijke queryschrijver die is gebaseerd op de gegevens van de querylezer. Deze nieuwe queryschrijver wordt vervolgens in het frame geplaatst.

Opnieuw werken deze bewerkingen om metagegevens te kopiëren alleen wanneer de bron- en doelafbeeldingen dezelfde indeling hebben. Dit komt doordat in verschillende afbeeldingsindelingen de metagegevensblokken op verschillende locaties worden opgeslagen. Zo ondersteunen zowel JPEG als TIFF XMP-metagegevensblokken. In JPEG-afbeeldingen bevindt het XMP-blok zich in het hoofdmetagegevensblok, zoals geïllustreerd in het WIC Metadata Overview. In een TIFF-afbeelding is het XMP-blok echter genest in een hoofd-IFD-blok. In het volgende diagram ziet u de verschillen tussen een JPEG-afbeelding en een TIFF-afbeelding met dezelfde classificatiemetagegevens.

jpeg- en tiffvergelijking.

Snelle metagegevenscodering

Het is niet altijd nodig om een afbeelding opnieuw te coderen om er nieuwe metagegevens naar te schrijven. Metagegevens kunnen ook worden geschreven met behulp van een snelle metagegevenscoderingsprogramma. Een snelle metagegevensencoder kan een beperkte hoeveelheid metagegevens naar een afbeelding schrijven zonder de afbeelding opnieuw te coderen. Dit wordt bereikt door de nieuwe metagegevens te schrijven binnen de lege opvulling die wordt geleverd door een aantal metagegevensindelingen. De systeemeigen indelingen voor metagegevens die ondersteuning bieden voor opvulling van metagegevens zijn Exif, IFD, GPS en XMP.

Opvulling toevoegen aan metagegevensblokken

Voordat u snelle metagegevenscodering kunt uitvoeren, moet er ruimte zijn binnen het metagegevensblok om meer metagegevens te schrijven. Als er onvoldoende ruimte is binnen de bestaande opvulling om de nieuwe metagegevens te schrijven, mislukt de snelle codering van metagegevens. Als u metagegevens wilt toevoegen aan een afbeelding, moet de afbeelding opnieuw worden gecodeerd. U kunt opvulling aan een metagegevensitem toevoegen op dezelfde manier als andere metagegevens, met een query-expressie, mits het metagegevensblok dat u opvult, dit ondersteunt. In het volgende voorbeeld ziet u hoe u opvulling toevoegt aan een IFD-blok dat is ingesloten in een App1-blok.

if (SUCCEEDED(hr))
{
    // Add metadata padding
    PROPVARIANT padding;

    PropVariantInit(&padding);
    padding.vt = VT_UI4;
    padding.uiVal = 4096; // 4KB

    hr = pFrameQWriter->SetMetadataByName(L"/app1/ifd/PaddingSchema:padding", &padding);

    PropVariantClear(&padding);
}

Als u opvulling wilt toevoegen, maakt u een PROPVARIANT van het type VT_UI4 en een waarde die overeenkomt met het aantal bytes aan opvulling dat moet worden toegevoegd. Een typische waarde is 4096 bytes. De metagegevensquery's voor JPEG, TIFF en JPEG-XR bevinden zich in deze tabel.

Indeling van metagegevens JPEG-metagegevensquery TIFF, JPEG-XR metagegevensquery
IFD /app1/ifd/PaddingSchema:Padding /ifd/PaddingSchema:Padding
EXIF /app1/ifd/exif/PaddingSchema:Padding /ifd/exif/PaddingSchema:Padding
XMP /xmp/PaddingSchema:Padding /ifd/xmp/PaddingSchema:Padding
GPS /app1/ifd/gps/PaddingSchema:Padding /ifd/gps/PaddingSchema:Padding

 

Een snelle metadatacoderer verkrijgen

Wanneer je een afbeelding met opvulling van metagegevens hebt, kun je een snelle metagegevensencoder verkrijgen met behulp van de methoden van de afbeeldingsfabriek CreateFastMetadataEncoderFromDecoder en CreateFastMetadataEncoderFromFrameDecode.

Zoals de naam al aangeeft, maakt CreateFastMetadataEncoderFromDecoder een snelle metagegevenscoderingsprogramma voor metagegevens op decoderniveau. De systeemeigen afbeeldingsindelingen die worden geleverd door WIC bieden geen ondersteuning voor metagegevens op decoderniveau, maar deze methode wordt geboden als een dergelijke afbeeldingsindeling in de toekomst wordt ontwikkeld.

Het meest voorkomende scenario is het verkrijgen van een snelle metagegevenscoder van een afbeeldingsframe met behulp van CreateFastMetadataEncoderFromFrameDecode. Met de volgende code wordt de snelle metagegevensencoder van het gedecodeerde frame opgehaald en wordt de beoordelingswaarde in het App1-blok gewijzigd.

if (SUCCEEDED(hr))
{
    IWICFastMetadataEncoder *pFME = NULL;
    IWICMetadataQueryWriter *pFMEQW = NULL;

    hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
        pFrameDecode, 
        &pFME);
}

De snelle metagegevenscoderingsprogramma gebruiken

Met de snelle metagegevensencoder kunt u een query-schrijver verkrijgen. Hiermee kunt u metagegevens schrijven met behulp van een query-expressie zoals eerder is gedemonstreerd. Nadat metagegevens zijn ingesteld in de queryschrijver, bevestigt u de snelle metagegevensencoder om de update van de metagegevens te voltooien. De volgende code demonstreert het instellen en doorvoeren van de metagegevenswijzigingen

    if (SUCCEEDED(hr))
    {
        hr = pFME->GetMetadataQueryWriter(&pFMEQW);
    }

    if (SUCCEEDED(hr))
    {
        // Add additional metadata
        PROPVARIANT value;

        PropVariantInit(&value);

        value.vt = VT_UI4;
        value.uiVal = 99;
        hr = pFMEQW->SetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);

        PropVariantClear(&value);
    }

    if (SUCCEEDED(hr))
    {
        hr = pFME->Commit();
    }
}

Als doorvoeren om welke reden dan ook mislukt, moet u de afbeelding opnieuw coderen om ervoor te zorgen dat de nieuwe metagegevens aan de afbeelding worden toegevoegd.

conceptuele

Overzicht van Windows Imaging-onderdelen

Overzicht van WIC-metagegevens

Overzicht van metagegevensquerytaal

Overzicht van de uitbreidbaarheid van metagegevens

Instructies: Een JPEG-afbeelding opnieuw coderen met metagegevens