Megosztás a következőn keresztül:


Kép metaadatainak olvasása és írása – áttekintés

Ez a témakör áttekintést nyújt arról, hogyan használhatja a Windows Képalkotó összetevő (WIC) API-kat a képfájlokba beágyazott metaadatok olvasására és írására.

Ez a témakör a következő szakaszokat tartalmazza.

Előfeltételek

A témakör megértéséhez ismernie kell a WIC metaadat-rendszert, ahogy az az WIC metaadatok áttekintésbentalálható. Ismernie kell a metaadatok olvasásához és írásához használt lekérdezési nyelvet is, a metaadatok lekérdezési nyelvének áttekintése .

Bevezetés

A WIC a rendszerképfájlokba ágyazott metaadatok olvasásához és írásához a komponensobjektum-modell (COM) összetevőit biztosítja az alkalmazásfejlesztőknek. A metaadatok olvasásának és írásának két módja van:

  • Lekérdezésolvasó/-író és lekérdezési kifejezés használata beágyazott blokkok vagy adott metaadatok metaadatainak lekérdezéséhez egy blokkon belül.
  • Metaadat-kezelő (metaadat-olvasó vagy metaadat-író) használata a metaadatblokkokban lévő beágyazott metaadatblokkok vagy adott metaadatok eléréséhez.

Ezek közül a legegyszerűbb, ha egy lekérdezésolvasót/írót és egy lekérdezési kifejezést használ a metaadatok eléréséhez. A lekérdezésolvasó (IWICMetadataQueryReader) metaadatok olvasására szolgál, míg a lekérdezésíró (IWICMetadataQueryWriter) metaadatok írására szolgál. Mindkettő lekérdezési kifejezést használ a kívánt metaadatok olvasásához vagy írásához. A háttérben a lekérdezésolvasó (és az író) metaadat-kezelővel fér hozzá a lekérdezési kifejezés által leírt metaadatokhoz.

A fejlettebb módszer a metaadat-kezelők közvetlen elérése. A metaadat-kezelő az egyes keretekből blokkolvasóval (IWICMetadataBlockReader) vagy blokkíróval (IWICMetadataBlockWriter) érhető el. A metaadat-kezelők két típusa érhető el: a metaadat-olvasó (IWICMetadataReader) és a metaadat-író (IWICMetadataWriter).

A jelen témakör példáiban egy JPEG-képfájl tartalmának alábbi diagramját használjuk. A diagram által ábrázolt kép a Microsoft Paint használatával jött létre; a minősítési metaadatokat a Windows Vista Fényképtár funkciójával adták hozzá.

jpeg kép illusztrációja a metaadatok minősítésével

Metadadata olvasása lekérdezésolvasó használatával

A metaadatok olvasásának legegyszerűbb módja a lekérdezésolvasó felület használata, IWICMetadataQueryReader. A lekérdezésolvasóval egy lekérdezési kifejezéssel olvashat metaadatblokkokat és elemeket a metaadatblokkokban.

A lekérdezésolvasót három módon szerezheti be: bitkép-dekódolón (IWICBitmapDecoder), az egyes kereteken (IWICBitmapFrameDecode) vagy egy lekérdezésírón (IWICMetadataQueryWriter).

Lekérdezésolvasó beszerzése

Az alábbi példakód bemutatja, hogyan szerezhet be bitkép-dekódert a képalkotó gyárból, és hogyan kérhet le egy adott bitképkeretet. Ez a kód elvégzi a lekérdezésolvasó dekódolt keretből való beszerzéséhez szükséges telepítési munkát is.

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

A test.jpg fájl bitkép-dekódolóját a képalkotó-előállító CreateDecoderFromFilename metódusával szerezheti be. Ebben a metódusban a negyedik paraméter a WICDecodeMetadataCacheOnDemand értékre van állítva a WICDecodeOptions enumerálásból. Ez tájékoztatja a dekódolót, hogy gyorsítótárazza a metaadatokat, amikor szükség van rájuk, akár egy lekérdezés-olvasó, akár a metaadat-olvasó segítségével történő beszerzéssel. Ezzel a beállítással megőrizheti a streamet a gyors metaadat-kódoláshoz szükséges metaadatokra, és lehetővé teszi a JPEG-kép veszteségmentes dekódolását. Másik lehetőségként használhatja a másik WICDecodeOptions értéket, a WICDecodeMetadataCacheOnLoad értéket, amely a kép betöltése után gyorsítótárazza a beágyazott kép metaadatait.

A keret lekérdezésolvasójának lekéréséhez hozzon létre egy egyszerű hívást a keret GetMetadataQueryReader metódushoz. Az alábbi kód bemutatja ezt a hívást.

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

Hasonlóképpen, a lekérdezésolvasó a dekóder szintjén is beszerezhető. A dekóder GetMetadataQueryReader metódus egyszerű hívással hozzáférhet a dekóder lekérdezésolvasójához. A dekóder lekérdezésolvasója a keret lekérdezésolvasójával ellentétben az egyes kereteken kívül eső kép metaadatait olvassa be. Ez a forgatókönyv azonban nem gyakori, és a natív képformátumok nem támogatják ezt a képességet. A WIC által biztosított natív képkódok a metaadatok olvasását és írását keretszinten végzik, még az egykeretes formátumok, például a JPEG esetében is.

Metaadatok olvasása

Mielőtt továbblép a metaadatok tényleges olvasására, tekintse meg a következő diagramot egy JPEG-fájlról, amely beágyazott metaadatblokkokat és tényleges adatokat tartalmaz a lekéréshez. Ez a diagram a kép adott metaadatblokkjait és elemeit jeleníti meg, amelyek az egyes blokkok vagy elemek metaadat-lekérdezési kifejezését tartalmazzák.

jpeg kép illusztrációja metaadatfeliratokkal

Beágyazott metaadatblokkok vagy adott elemek név szerinti lekérdezéséhez hívja meg a GetMetadataByName metódust. Ez a metódus egy lekérdezési kifejezést és egy PROPVARIANT vesz igénybe, amelyben a metaadat-elem vissza lesz adva. A következő kód lekérdez egy beágyazott metaadatblokkot, és a PROPVARIANT érték által biztosított IUnknown összetevőt lekérdezésolvasóvá alakítja, ha az megtalálható.

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
}

Az "/app1/ifd" lekérdezési kifejezés az App1 blokkba beágyazott IFD-blokkra kérdez le. A JPEG-képfájl tartalmazza az IFD beágyazott metaadatblokkot, így a PROPVARIANT egy VT_UNKNOWN típusú változóval (vt) és egy IUnknown felületre mutató pointerrel (punkVal) lesz visszaadva. Ezután lekérdezi az IUnknown felületet egy lekérdezésolvasóhoz.

Az alábbi kód egy új lekérdezést mutat be az új lekérdezésolvasó alapján a beágyazott IFD-blokkhoz képest.

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

A "/{ushort=18249}" lekérdezési kifejezés lekérdezi az 18249-ben beágyazott MicrosoftPhoto-minősítés IFD-blokkját. A PROPVARIANT érték mostantól VT_UI2 típusú és 50-es adatértéket tartalmaz.

Adott adatértékek lekérdezése előtt azonban nem szükséges beágyazott blokkot beszerezni. Például a beágyazott IFD, majd a MicrosoftPhoto minősítés lekérdezése helyett használhatja a fő metaadatblokkot és az alábbi kódban látható lekérdezést, hogy ugyanazokat az információkat szerezze be.

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

A metaadatblokkok adott metaadat-elemeinek lekérdezése mellett a metaadatblokk összes metaadatelemét is számba veheti (a metaadatelemeket nem beleértve a beágyazott metaadatblokkokban). Az aktuális blokk metaadat-elemeinek számbavételéhez a rendszer a lekérdezésolvasó GetEnumeration metódusát használja. Ez a metódus egy IEnumString felületet szerez be, amely az aktuális blokk metaadatelemeivel van feltöltve. Az alábbi kód például a korábban beszerzett beágyazott IFD-blokk XMP-minősítését és MicrosoftPhoto-minősítését sorolja fel.

IEnumString *metadataItems = NULL;

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

A különböző képformátumok és metaadatformátumok megfelelő címkéinek azonosításáról további információt Natív képformátumú metaadat-lekérdezésekcímű témakörben talál.

További lekérdezésolvasó metódusok

A metaadatok olvasása mellett további információkat is beszerezhet a lekérdezésolvasóról, és más módokon is beszerezheti a metaadatokat. A lekérdezésolvasó két módszert biztosít, amelyek információt nyújtanak a lekérdezésolvasóról, GetContainerFormat és GetLocation.

A beágyazott lekérdezésolvasóval a GetContainerFormat segítségével meghatározhatja a metaadat-blokk típusát, és meghívhatja GetLocation, hogy lekérje az elérési utat a fő metaadat-blokkhoz képest. Az alábbi kód lekérdezi a beágyazott lekérdezésolvasó helyét.

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

A beágyazott lekérdezésolvasó GetContainerFormat hívása az IFD metaadat-formátum GUID-értékét adja vissza. A GetLocation hívás "/app1/ifd" névteret ad vissza, amely megadja a relatív elérési utat, ahonnan az új lekérdezés olvasó számára érkező későbbi lekérdezéseket végrehajtják. Az előző kód természetesen nem túl hasznos, de bemutatja, hogyan használható a GetLocation metódus beágyazott metaadatblokkok keresésére.

Metaadatok írása lekérdezésíró használatával

Jegyzet

Az ebben a szakaszban szereplő kód példák némelyike nem jelenik meg a metaadatok írásához szükséges tényleges lépések kontextusában. Ha egy működő minta kontextusában szeretné megtekinteni a példakódokat, tekintse meg a How-to: Recode an Image with Metadata tutorial (Kép újrakódolása metaadatokkal) című oktatóanyagot.

 

A metaadatok írásának fő összetevője a lekérdezésíró (IWICMetadataQueryWriter). A lekérdezésíróval metaadatblokkokat és elemeket állíthat be és távolíthat el a metaadatblokkokban.

A lekérdezésolvasóhoz hasonlóan a lekérdezésírók beszerzésének három módja van: bitkép-kódolón (IWICBitmapEncoder), az egyes kereteken (IWICBitmapFrameEncode) vagy egy gyors metaadat-kódolón (IWICFastMetadataEncoder).

Lekérdezésíró beszerzése

A leggyakrabban használt lekérdezésíró egy bitkép egy-egy keretéhez tartozik. Ez a lekérdezésíró beállítja és eltávolítja egy képkeret metaadatblokkjait és elemeit. A képkeret lekérdezésírójának lekéréséhez hívja meg a keret GetMetadataQueryWriter metódusát. Az alábbi kód bemutatja a keret lekérdezésírójának lekéréséhez szükséges egyszerű metódushívást.

IWICMetadataQueryWriter &pFrameQWriter = NULL;

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

Hasonlóképpen a kódoló szintjén is beszerezhető egy lekérdezésíró. A kódoló GetMetadataQueryWriter metódus egyszerű hívásával lekéri a kódoló lekérdezésíróját. A kódoló lekérdezésírója a keret lekérdezésírójával ellentétben az egyes kereten kívüli képek metaadatait írja. Ez a forgatókönyv azonban nem gyakori, és a natív képformátumok nem támogatják ezt a képességet. A WIC által biztosított natív képkodekek a metaadatokat a keret szintjén olvassák és írják, még az egykeretes formátumok, például a JPEG esetében is.

A lekérdezésírót közvetlenül a képalkotó gyárból (IWICImagingFactory) is beszerezheti. Két képalkotó gyári metódus van, amelyek egy lekérdezésírót adnak vissza: CreateQueryWriter és CreateQueryWriterFromReader.

CreateQueryWriter létrehoz egy lekérdezésírót a megadott metaadatformátumhoz és szállítóhoz. Ez a lekérdezésíró lehetővé teszi, hogy metaadatokat írjon egy adott metaadat-formátumhoz, és hozzáadja azt a képhez. Az alábbi kód egy XMP-lekérdezésíró létrehozásához CreateQueryWriter hívását mutatja be.

IWICMetadataQueryWriter *pXMPWriter = NULL;

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

A példában a GUID_MetadataFormatXMP barátságos név a guidMetadataFormat paraméterként van használva. Ez az XMP-metaadatok GUID formátumú formátumát, a szállító pedig a Microsoft által létrehozott kezelőt jelöli. Másik lehetőségként NULL is átadható, mint a pguidVendor paraméter ugyanazzal az eredménnyel, ha nincs más XMP-kezelő. Ha a natív XMP-kezelő mellett egyéni XMP-kezelő van telepítve, a szállító paraméterként átadott NULL érték eredményeként az a lekérdezésíró kerül visszaadásra, amelyikhez a legalacsonyabb GUID tartozik.

CreateQueryWriterFromReader hasonló a CreateQueryWriter metódushoz, azzal a kivétellel, hogy előre feltölti az új lekérdezésírót a lekérdezésolvasó által megadott adatokkal. Ez hasznos lehet egy kép újrakódolásához a meglévő metaadatok fenntartása mellett, vagy a nem kívánt metaadatok eltávolításához. Az alábbi kód egy CreateQueryWriterFromReader hívást mutat be.

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

Metaadatok hozzáadása

A lekérdezésíró beszerzése után metaadatblokkokat és elemeket adhat hozzá. Metaadatok írásához a lekérdezésíró SetMetadataByName metódusát kell használnia. SetMetadataByName két paramétert használ: egy lekérdezési kifejezést (wzName) és egy mutatót egy PROPVARIANT (pvarValue). A lekérdezési kifejezés meghatározza a beállítandó blokkot vagy elemet, amíg a PROPVARIANT megadja a beállítani kívánt tényleges adatértéket.

Az alábbi példa bemutatja, hogyan adhat hozzá címet a korábban a CreateQueryWriter metódussal beszerzett XMP-lekérdezésíróval.

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

Ebben a példában az érték típusa (vt) VT_LPWSTRértékre van állítva, ami azt jelzi, hogy egy sztring lesz az adatérték. Mivel a értéktípusa sztring, a pwszVal-t használják a cím beállítására. SetMetadataByName ezután a "/dc:title" lekérdezési kifejezés és az újonnan beállított PROPVARIANThasználatával hívjuk meg. A használt lekérdezési kifejezés azt jelzi, hogy a digitális kamera (dc) sémájának címtulajdonságát be kell állítani. Vegye figyelembe, hogy a kifejezés nem "/xmp/dc:title"; Ennek az az oka, hogy a lekérdezésíró már kifejezetten az XMP-hez tartozik, és nem tartalmaz beágyazott XMP-blokkot, amelyet a "/xmp/dc:title" javasolna.

Eddig nem adtál hozzá metaadatokat a képkerethez. Egyszerűen adatokkal töltött ki egy lekérdezésszerkesztőt. Ha egy kerethez szeretne hozzáadni egy metaadatblokkot, amelyet a lekérdezésíró képvisel, akkor újra hívja meg a SetMetadataByName függvényt, és a lekérdezésírót adja meg a PROPVARIANTértékeként. Ezzel gyakorlatilag átmásolja a lekérdezésíró metaadatait a képkeretbe. Az alábbi kód bemutatja, hogyan adhatja hozzá a korábban beszerzett XMP-lekérdezésíró metaadatait a keret gyökér metaadatblokkjába.

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

Ebben a példában a VT_UNKOWN értéktípusát (vt) használjuk; a COM-felület értéktípusát jelzi. Az XMP-lekérdezésíró (piXMPWriter) ezután a PROPVARIANTértékeként lesz használva, és az AddRef metódussal hivatkozik rá. Végül az XMP-lekérdezésíró úgy van beállítva, hogy meghívja a keret SetMetadataByName metódust, és átadja a "/" lekérdezési kifejezést, amely a gyökérblokkot és az újonnan beállított PROPVARIANT-t jelzi.

Jegyzet

Ha a keret már tartalmazza a hozzáadni kívánt metaadatblokkot, a rendszer hozzáadja a hozzáadni kívánt metaadatokat, és felülírja a meglévő metaadatokat.

 

Metaadatok eltávolítása

A lekérdezésíró lehetővé teszi a metaadatok eltávolítását a RemoveMetadataByName metódus meghívásával. RemoveMetadataByName lekérdezési kifejezést vesz fel, és eltávolítja a metaadatblokkot vagy -elemet, ha létezik. Az alábbi kód bemutatja, hogyan távolítható el a korábban hozzáadott cím.

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

Az alábbi kód bemutatja, hogyan távolíthatja el a teljes XMP-metaadatblokkot.

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

Metaadatok másolása újrakódoláshoz

Jegyzet

Az ebben a szakaszban szereplő kód csak akkor érvényes, ha a forrás- és a célrendszerkép formátuma megegyezik. Nem másolhatja egy kép összes metaadatait egyetlen műveletben, ha más képformátumba kódolást használ.

 

Ha meg szeretné őrizni a metaadatokat, miközben a rendszerképet ugyanarra a képformátumra kódolja, léteznek módszerek az összes metaadat egyetlen műveletben való másolására. Mindegyik művelet hasonló mintát követ; mindegyik a dekódolt keret metaadatait közvetlenül a kódolt új keretbe állítja be.

A metaadatok másolásának elsődleges módja az új keret blokkírójának inicializálása a dekódolt keret blokkolvasójával. Az alábbi kód ezt a módszert mutatja be.

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

Ebben a példában a blokkolvasó és a blokkíró a forráskeretből és a célkeretből származik. A blokkíró ezután inicializálva lesz a blokkolvasóból. Ez inicializálja a blokkolvasót a blokkolvasó előre kitöltött metaadataival.

A metaadatok másolásának másik módja a lekérdezésolvasó által hivatkozott metaadat-blokk írása a kódoló lekérdezésírójával. Az alábbi kód ezt a módszert mutatja be.

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

Itt a rendszer lekérte a lekérdezésolvasót a dekódolt keretből, majd a PROPVARIANT tulajdonságértékeként használja VT_UNKNOWN értéktípussal. A rendszer lekéri a kódoló lekérdezésíróját, és a "/" lekérdezési kifejezést használja a metaadatok beállításához a fő navigációs útvonalon. Ezt a módszert a beágyazott metaadatblokkok beállításához is használhatja, ha a lekérdezési kifejezést a kívánt helyre állítja.

Hasonlóképpen létrehozhat egy lekérdezésírót a dekódolt keret lekérdezésolvasója alapján a képalkotó-előállító CreateQueryWriterFromReader metódusával. Az ebben a műveletben létrehozott lekérdezésírót a rendszer előre feltölti a lekérdezésolvasó metaadataival, majd a keretbe állíthatja. Az alábbi kód bemutatja a CreateQueryWriterFromReader másolási műveletet.

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

Ez a metódus egy külön lekérdezésírót használ, amely a lekérdezésolvasó adatain alapul. Ez az új lekérdezésíró ezután a keretbe kerül.

Ezek a metaadatok másolására vonatkozó műveletek szintén csak akkor működnek, ha a forrás- és célrendszerképek formátuma megegyezik. Ennek az az oka, hogy a különböző képformátumok különböző helyeken tárolják a metaadatblokkokat. A JPEG és a TIFF is támogatja például az XMP metaadatblokkokat. JPEG-képeken az XMP-blokk a metaadatok legfelső szintű blokkjában található, ahogyan az WIC Metadata Overviewcímű témakörben látható. Egy TIFF-rendszerképben azonban az XMP-blokk egy gyökér HAD-blokkba van ágyazva. Az alábbi ábra a JPEG-képek és az azonos minősítési metaadatokat tartalmazó TIFF-képek közötti különbségeket mutatja be.

jpeg és tiff összehasonlítása.

Gyors metaadatok kódolása

Nem mindig szükséges újrakódolni egy képet új metaadatok írásához. A metaadatok gyors metaadat-kódolóval is megírhatók. A gyors metaadat-kódolók korlátozott mennyiségű metaadatot írhatnak egy képre a kép újrakódolása nélkül. Ezt úgy lehet megvalósítani, hogy az új metaadatokat a metaadat-formátumok által biztosított üres helyre írja be. A metaadat-pótlást támogató natív metaadat-formátumok az Exif, az IFD, a GPS és az XMP.

Párnázás hozzáadása metaadat-blokkokhoz

Mielőtt gyors metaadat-kódolást végezhetne, helynek kell lennie a metaadatblokkon belül, hogy további metaadatokat írhasson. Ha nincs elég hely a meglévő kitöltésben az új metaadatok írásához, a gyors metaadat-kódolás sikertelen lesz. Ha metaadat-párnázást szeretne hozzáadni egy képhez, a képet újra kell kódolni. Ugyanúgy adhat hozzá kitöltést, mint bármely más metaadatelemet egy lekérdezési kifejezéssel, ha a kipárnázott metaadatblokk támogatja azt. Az alábbi példa bemutatja, hogyan adhat hozzá kitöltést egy IFD-blokkhoz, amely egy App1-blokkba van beágyazva.

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

A kitöltés hozzáadásához hozzon létre egy VT_UI4 típusú PROPVARIANT-t, valamint egy olyan értéket, amely a hozzáadandó bájtok számának felel meg. Egy tipikus érték 4096 bájt. A JPEG, a TIFF és a JPEG-XR metaadat-lekérdezései ebben a táblázatban találhatók.

Metaadatok formátuma JPEG-metaadat-lekérdezés TIFF, JPEG-XR metaadat-lekérdezés
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

 

Gyors metaadatok kódolójának beszerzése

Ha egy olyan képe van, amely metaadat-kitöltést tartalmaz, az imaging factory metódusokkal gyors metaadat-kódolót szerezhet be, CreateFastMetadataEncoderFromDecoder és CreateFastMetadataEncoderFromFrameDecode.

Ahogy a neve is mutatja, CreateFastMetadataEncoderFromDecoder létrehoz egy gyors metaadat-kódolót a dekóderszintű metaadatokhoz. A WIC által biztosított natív képformátumok nem támogatják a dekóderszintű metaadatokat, de ez a módszer akkor érhető el, ha a jövőben ilyen képformátumot fejlesztenek ki.

A leggyakoribb forgatókönyv egy gyors metaadat-kódoló lekérése egy képkeretből CreateFastMetadataEncoderFromFrameDecodehasználatával. Az alábbi kód lekérte a dekódolt keret gyors metaadat-kódolóját, és módosítja a minősítési értéket az App1 blokkban.

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

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

A Fast Metadata Encoder használata

A gyors metaadat-kódolóból lekérdezésírót szerezhet be. Ez lehetővé teszi a metaadatok írását a korábban bemutatott lekérdezési kifejezéssel. Miután beállította a metaadatokat a lekérdezésíróban, véglegesítse a gyors metaadat-kódolót a frissítés befejezéséhez. Az alábbi kód bemutatja a metaadatok módosításainak beállítását és véglegesítését

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

Ha a commit bármilyen okból meghiúsul, újra kell kódolnia a képet, hogy az új metaadatok bekerüljenek a fájlba.

fogalmi

Windows képalkotó összetevő áttekintése

WIC-metaadatok áttekintése

metaadatok lekérdezési nyelvének áttekintése

metaadatok bővíthetőségének áttekintése

Útmutató: JPEG-kép újrakódolása metaadatokkal