Gambaran Umum Membaca dan Menulis Metadata Gambar

Topik ini memberikan gambaran umum tentang bagaimana Anda dapat menggunakan API Komponen Pencitraan Windows (WIC) untuk membaca dan menulis metadata yang disematkan dalam file gambar.

Topik ini berisi bagian berikut.

Prasyarat

Untuk memahami topik ini, Anda harus terbiasa dengan sistem metadata WIC seperti yang dijelaskan dalam Gambaran Umum Metadata WIC. Anda juga harus terbiasa dengan bahasa kueri yang digunakan untuk membaca dan menulis metadata, seperti yang dijelaskan dalam Gambaran Umum Bahasa Kueri Metadata.

Pengantar

WIC menyediakan komponen Component Object Model (COM) kepada pengembang aplikasi untuk membaca dan menulis metadata yang disematkan dalam file gambar. Ada dua cara untuk membaca dan menulis metadata:

  • Menggunakan pembaca/penulis kueri dan ekspresi kueri untuk mengkueri blok metadata untuk blok berlapis atau metadata tertentu dalam blok.
  • Menggunakan penangan metadata (pembaca metadata atau penulis metadata) untuk mengakses blok metadata berlapis atau metadata tertentu dalam blok metadata.

Yang paling mudah adalah menggunakan pembaca/penulis kueri dan ekspresi kueri untuk mengakses metadata. Pembaca kueri (IWICMetadataQueryReader) digunakan untuk membaca metadata sementara penulis kueri (IWICMetadataQueryWriter) digunakan untuk menulis metadata. Kedua hal ini menggunakan ekspresi kueri untuk membaca atau menulis metadata yang diinginkan. Di balik layar, pembaca kueri (dan penulis) menggunakan penangan metadata untuk mengakses metadata yang dijelaskan oleh ekspresi kueri.

Metode yang lebih canggih adalah langsung mengakses penangan metadata. Handler metadata diperoleh dari bingkai individual menggunakan pembaca blok (IWICMetadataBlockReader) atau penulis blok (IWICMetadataBlockWriter). Dua jenis penangan metadata yang tersedia adalah pembaca metadata (IWICMetadataReader) dan penulis metadata (IWICMetadataWriter).

Diagram konten file gambar JPEG berikut digunakan di seluruh contoh dalam topik ini. Gambar yang diwakili oleh diagram ini dibuat dengan menggunakan Microsoft Paint; metadata peringkat ditambahkan dengan menggunakan fitur Galeri Foto Windows Vista.

ilustrasi gambar jpeg dengan metadata peringkat

Membaca Metadadata Menggunakan Pembaca Kueri

Cara termampu untuk membaca metadata adalah dengan menggunakan antarmuka pembaca kueri, IWICMetadataQueryReader. Pembaca kueri memungkinkan Anda membaca blok metadata dan item dalam blok metadata menggunakan ekspresi kueri.

Ada tiga cara untuk mendapatkan pembaca kueri: melalui dekoder bitmap (IWICBitmapDecoder), melalui bingkai individualnya (IWICBitmapFrameDecode), atau melalui penulis kueri (IWICMetadataQueryWriter).

Mendapatkan Pembaca Kueri

Contoh kode berikut menunjukkan cara mendapatkan dekoder bitmap dari pabrik pencitraan dan mengambil bingkai bitmap individual. Kode ini juga melakukan pekerjaan penyiapan yang diperlukan untuk mendapatkan pembaca kueri dari bingkai yang didekodekan.

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

Dekoder bitmap untuk file test.jpg diperoleh dengan menggunakan metode CreateDecoderFromFilename dari pabrik pencitraan. Dalam metode ini, parameter keempat diatur ke nilai WICDecodeMetadataCacheOnDemand dari enumerasi WICDecodeOptions . Ini memberi tahu dekoder untuk menyimpan metadata ketika metadata diperlukan; baik dengan mendapatkan pembaca kueri atau pembaca metadata yang mendasar. Menggunakan opsi ini memungkinkan Anda mempertahankan aliran ke metadata yang diperlukan untuk pengodean metadata cepat dan memungkinkan decoding tanpa kehilangan gambar JPEG. Atau, Anda dapat menggunakan nilai WICDecodeOptions lainnya, WICDecodeMetadataCacheOnLoad, yang menyimpan metadata gambar yang disematkan segera setelah gambar dimuat.

Untuk mendapatkan pembaca kueri bingkai, lakukan panggilan sederhana ke metode GetMetadataQueryReader bingkai. Kode berikut menunjukkan panggilan ini.

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

Demikian pula, pembaca kueri juga dapat diperoleh pada tingkat dekoder. Panggilan sederhana ke metode GetMetadataQueryReader decoder mendapatkan pembaca kueri dekoder. Pembaca kueri dekoder, tidak seperti pembaca kueri bingkai, membaca metadata untuk gambar yang berada di luar bingkai individual. Namun, skenario ini tidak umum, dan format gambar asli tidak mendukung kemampuan ini. CODEC gambar asli yang disediakan oleh WIC membaca dan menulis metadata pada tingkat bingkai bahkan untuk format bingkai tunggal seperti JPEG.

Membaca Metadata

Sebelum Anda beralih ke benar-benar membaca metadata, lihat diagram file JPEG berikut yang menyertakan blok metadata yang disematkan dan data aktual untuk diambil. Diagram ini menyediakan panggilan ke blok metadata dan item tertentu dalam gambar yang menyediakan ekspresi kueri metadata untuk setiap blok atau item.

ilustrasi gambar jpeg dengan callout metadata

Untuk mengkueri blok metadata yang disematkan atau item tertentu berdasarkan nama, panggil metode GetMetadataByName . Metode ini mengambil ekspresi kueri dan PROPVARIANT tempat item metadata dikembalikan. Kode berikut mengkueri blok metadata berlapis dan mengonversi komponen IUnknown yang disediakan oleh nilai PROPVARIANT ke pembaca kueri jika ditemukan.

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
}

Ekspresi kueri "/app1/ifd" mengkueri blok IFD yang ditumpuk di blok App1. File gambar JPEG berisi blok metadata berlapis IFD, sehingga PROPVARIANT dikembalikan dengan jenis variabel (vt) VT_UNKNOWN dan pointer ke antarmuka IUnknown (punkVal). Anda kemudian mengkueri antarmuka IUnknown untuk pembaca kueri.

Kode berikut menunjukkan kueri baru berdasarkan pembaca kueri baru relatif terhadap blok IFD berlapis.

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

Ekspresi kueri "/{ushort=18249}" meminta blok IFD untuk peringkat MicrosoftPhoto yang disematkan di bawah tag 18249. Nilai PROPVARIANT sekarang akan berisi jenis VT_UI2 nilai dan nilai data 50.

Namun, tidak perlu mendapatkan blok berlapis sebelum mengkueri nilai data tertentu. Misalnya, alih-alih mengkueri IFD berlapis dan kemudian untuk peringkat MicrosoftPhoto, Anda dapat menggunakan blok metadata akar dan kueri yang diperlihatkan dalam kode berikut untuk mendapatkan informasi yang sama.

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

Selain mengkueri item metadata tertentu dalam blok metadata, Anda juga dapat menghitung semua item metadata dalam blok metadata (tidak termasuk item metadata dalam blok metadata berlapis). Untuk menghitung item metadata di blok saat ini, metode GetEnumeration pembaca kueri digunakan. Metode ini mendapatkan antarmuka IEnumString yang diisi dengan item metadata di blok saat ini. Misalnya, kode berikut menghitung peringkat XMP dan peringkat MicrosoftPhoto untuk blok IFD berlapis yang diperoleh sebelumnya.

IEnumString *metadataItems = NULL;

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

Untuk informasi selengkapnya tentang mengidentifikasi tag yang sesuai untuk berbagai format gambar dan format metadata, lihat Kueri Metadata Format Gambar Asli.

Metode Pembaca Kueri Tambahan

Selain membaca metadata, Anda juga bisa mendapatkan informasi tambahan tentang pembaca kueri dan mendapatkan metadata melalui cara lain. Pembaca kueri menyediakan dua metode yang menyediakan informasi tentang pembaca kueri, GetContainerFormat dan GetLocation.

Dengan pembaca kueri yang disematkan, Anda dapat menggunakan GetContainerFormat untuk menentukan jenis blok metadata, dan Anda dapat memanggil GetLocation untuk mendapatkan jalur relatif terhadap blok metadata akar. Kode berikut meminta pembaca kueri yang disematkan untuk lokasinya.

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

Panggilan ke GetContainerFormat untuk pembaca kueri yang disematkan mengembalikan GUID format metadata IFD. Panggilan ke GetLocation mengembalikan namespace "/app1/ifd"; memberi Anda jalur relatif tempat kueri berikutnya ke pembaca kueri baru akan dijalankan. Tentu saja, kode sebelumnya tidak terlalu berguna, tetapi menunjukkan cara menggunakan metode GetLocation untuk menemukan blok metadata berlapis.

Menulis Metadata Menggunakan Penulis Kueri

Catatan

Beberapa contoh kode yang disediakan di bagian ini tidak ditampilkan dalam konteks langkah-langkah aktual yang diperlukan untuk menulis metadata. Untuk melihat contoh kode dalam konteks sampel yang berfungsi, lihat tutorial Cara: Mengodekan ulang Gambar dengan Metadata.

 

Komponen utama untuk menulis metadata adalah penulis kueri (IWICMetadataQueryWriter). Penulis kueri memungkinkan Anda mengatur dan menghapus blok metadata dan item dalam blok metadata.

Seperti pembaca kueri, ada tiga cara untuk mendapatkan penulis kueri: melalui encoder bitmap (IWICBitmapEncoder), melalui bingkai individualnya (IWICBitmapFrameEncode), atau melalui encoder metadata cepat (IWICFastMetadataEncoder).

Mendapatkan Penulis Kueri

Penulis kueri yang paling umum adalah untuk bingkai individual bitmap. Penulis kueri ini mengatur dan menghapus blok metadata dan item bingkai gambar. Untuk mendapatkan penulis kueri bingkai gambar, panggil metode GetMetadataQueryWriter bingkai. Kode berikut menunjukkan panggilan metode sederhana untuk mendapatkan penulis kueri bingkai.

IWICMetadataQueryWriter &pFrameQWriter = NULL;

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

Demikian pula, penulis kueri juga dapat diperoleh untuk tingkat encoder. Panggilan sederhana ke metode GetMetadataQueryWriter encoder mendapatkan penulis kueri encoder. Penulis kueri encoder, tidak seperti penulis kueri bingkai, menulis metadata untuk gambar di luar bingkai individual. Namun, skenario ini tidak umum, dan format gambar asli tidak mendukung kemampuan ini. Codec gambar asli yang disediakan oleh metadata baca dan tulis WIC pada tingkat bingkai bahkan untuk format bingkai tunggal seperti JPEG.

Anda juga dapat memperoleh penulis kueri langsung dari pabrik pencitraan (IWICImagingFactory). Ada dua metode pabrik pencitraan yang mengembalikan penulis kueri: CreateQueryWriter dan CreateQueryWriterFromReader.

CreateQueryWriter membuat penulis kueri untuk format metadata dan vendor yang ditentukan. Penulis kueri ini memungkinkan Anda menulis metadata untuk format metadata tertentu dan menambahkannya ke gambar. Kode berikut menunjukkan panggilan CreateQueryWriter untuk membuat penulis kueri XMP.

IWICMetadataQueryWriter *pXMPWriter = NULL;

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

Dalam contoh ini, nama GUID_MetadataFormatXMP yang mudah diingat digunakan sebagai parameter guidMetadataFormat . Ini mewakili GUID format metadata XMP, dan vendor mewakili handler yang dibuat Microsoft. Atau, NULL dapat diteruskan sebagai parameter pguidVendor dengan hasil yang sama jika tidak ada handler XMP lainnya. Jika handler XMP kustom diinstal bersama handler XMP asli, meneruskan NULL untuk vendor akan menghasilkan penulis kueri dengan GUID terendah yang dikembalikan.

CreateQueryWriterFromReader mirip dengan metode CreateQueryWriter kecuali telah mengisi penulis kueri baru dengan data yang disediakan oleh pembaca kueri. Ini berguna untuk mengodekan ulang gambar sambil mempertahankan metadata yang ada, atau untuk menghapus metadata yang tidak diinginkan. Kode berikut menunjukkan panggilan CreateQueryWriterFromReader .

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

Menambahkan Metadata

Setelah mendapatkan penulis kueri, Anda bisa menggunakannya untuk menambahkan blok metadata dan item. Untuk menulis metadata, Anda menggunakan metode SetMetadataByName penulis kueri. SetMetadataByName mengambil dua parameter: ekspresi kueri (wzName) dan penunjuk ke PROPVARIANT (pvarValue). Ekspresi kueri menentukan blok atau item yang akan diatur sementara PROPVARIANT menyediakan nilai data aktual untuk diatur.

Contoh berikut menunjukkan cara menambahkan judul dengan menggunakan penulis kueri XMP yang sebelumnya diperoleh dengan menggunakan metode 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);
}

Dalam contoh ini, jenis nilai (vt) diatur ke VT_LPWSTR, menunjukkan bahwa string akan digunakan sebagai nilai data. Karena jenis nilai adalah string, pwszVal digunakan untuk mengatur judul yang akan digunakan. SetMetadataByName kemudian dipanggil menggunakan ekspresi kueri "/dc:title" dan PROPVARIANT yang baru diatur. Ekspresi kueri yang digunakan menunjukkan bahwa properti judul dalam skema kamera digital (dc) harus diatur. Perhatikan bahwa ekspresi bukan "/xmp/dc:title"; ini karena penulis kueri sudah khusus untuk XMP dan tidak berisi blok XMP yang disematkan, yang akan disarankan "/xmp/dc:title".

Hingga saat ini Anda belum benar-benar menambahkan metadata apa pun ke bingkai gambar. Anda hanya mengisi penulis kueri dengan data. Untuk menambahkan ke bingkai blok metadata yang diwakili oleh penulis kueri, Anda kembali memanggil SetMetadataByName menggunakan penulis kueri sebagai nilai PROPVARIANT. Ini secara efektif menyalin metadata di penulis kueri ke bingkai gambar. Kode berikut menunjukkan cara menambahkan metadata di penulis kueri XMP yang sebelumnya diperoleh ke blok metadata akar bingkai.

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

Dalam contoh ini, jenis nilai (vt) VT_UNKOWN digunakan; menunjukkan jenis nilai antarmuka COM. Penulis kueri XMP (piXMPWriter) kemudian digunakan sebagai nilai PROPVARIANT, menambahkan referensi ke dalamnya dengan menggunakan metode AddRef. Terakhir, penulis kueri XMP diatur dengan memanggil metode SetMetadataByName bingkai dan meneruskan ekspresi kueri "/", menunjukkan blok akar, dan PROPVARIANT yang baru diatur.

Catatan

Jika bingkai sudah berisi blok metadata yang coba Anda tambahkan, metadata yang Anda tambahkan akan ditambahkan dan metadata yang ada ditimpa.

 

Menghapus Metadata

Penulis kueri juga memungkinkan Anda menghapus metadata dengan memanggil metode RemoveMetadataByName . RemoveMetadataByName mengambil ekspresi kueri dan menghapus blok metadata atau item jika ada. Kode berikut menunjukkan cara menghapus judul yang sebelumnya ditambahkan.

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

Kode berikut menunjukkan cara menghapus seluruh blok metadata XMP.

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

Menyalin Metadata untuk Pengodean Ulang

Catatan

Kode di bagian ini hanya valid ketika format gambar sumber dan tujuan sama. Anda tidak dapat menyalin semua metadata gambar dalam satu operasi saat mengodekan ke format gambar yang berbeda.

 

Untuk mempertahankan metadata saat mengodekan ulang gambar ke format gambar yang sama, ada metode yang tersedia untuk menyalin semua metadata dalam satu operasi. Masing-masing operasi ini mengikuti pola yang sama; masing-masing mengatur metadata bingkai yang didekodekan langsung ke bingkai baru yang dikodekan.

Metode yang disukai untuk menyalin metadata adalah menginisialisasi penulis blok bingkai baru dengan pembaca blok bingkai yang didekodekan. Kode berikut menunjukkan metode ini.

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

Dalam contoh ini, pembaca blok dan penulis blok diperoleh dari bingkai sumber dan bingkai tujuan, masing-masing. Penulis blok kemudian diinisialisasi dari pembaca blok. Ini menginisialisasi pembaca blok dengan metadata pembaca blok yang telah diisi sebelumnya.

Metode lain untuk menyalin metadata adalah menulis blok metadata yang dirujuk oleh pembaca kueri menggunakan penulis kueri encoder. Kode berikut menunjukkan metode ini.

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

Di sini, pembaca kueri diperoleh dari bingkai yang didekodekan lalu digunakan sebagai nilai properti PROPVARIANT dengan jenis nilai yang diatur ke VT_UNKNOWN. Penulis kueri untuk encoder diperoleh dan ekspresi kueri "/" digunakan untuk mengatur metadata di jalur navigasi akar. Anda juga dapat menggunakan metode ini saat mengatur blok metadata berlapis, dengan menyesuaikan ekspresi kueri ke lokasi yang diinginkan.

Demikian pula, Anda dapat membuat penulis kueri berdasarkan pembaca kueri bingkai yang didekode dengan menggunakan metode CreateQueryWriterFromReader pabrik pencitraan. Penulis kueri yang dibuat dalam operasi ini akan diisi sebelumnya dengan metadata dari pembaca kueri dan kemudian dapat diatur dalam bingkai. Kode berikut menunjukkan operasi salin CreateQueryWriterFromReader .

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

Metode ini menggunakan penulis kueri terpisah dibuat yang didasarkan pada data pembaca kueri. Penulis kueri baru ini kemudian diatur dalam bingkai.

Sekali lagi, operasi ini untuk menyalin metadata hanya berfungsi ketika gambar sumber dan tujuan memiliki format yang sama. Ini karena format gambar yang berbeda menyimpan blok metadata di lokasi yang berbeda. Misalnya, JPEG dan TIFF mendukung blok metadata XMP. Dalam gambar JPEG, blok XMP berada di blok metadata akar seperti yang diilustrasikan dalam Gambaran Umum Metadata WIC. Namun, dalam gambar TIFF, blok XMP berlapis di blok IFD akar. Diagram berikut mengilustrasikan perbedaan antara gambar JPEG dan gambar TIFF dengan metadata peringkat yang sama.

perbandingan jpeg dan tiff.

Pengodean Metadata Cepat

Tidak selalu perlu mengodekan ulang gambar untuk menulis metadata baru ke dalamnya. Metadata juga dapat ditulis dengan menggunakan encoder metadata cepat. Encoder metadata cepat dapat menulis sejumlah metadata terbatas ke gambar tanpa mengodekan ulang gambar. Ini dicapai dengan menulis metadata baru dalam padding kosong yang disediakan oleh beberapa format metadata. Format metadata asli yang mendukung padding metadata adalah Exif, IFD, GPS, dan XMP.

Menambahkan Padding ke Blok Metadata

Sebelum Anda dapat melakukan pengodean metadata cepat, harus ada ruang dalam blok metadata untuk menulis lebih banyak metadata. Jika tidak ada cukup ruang dalam padding yang ada untuk menulis metadata baru, pengodean metadata cepat akan gagal. Untuk menambahkan padding metadata ke gambar, gambar harus dikodekan ulang. Anda dapat menambahkan padding dengan cara yang sama seperti Anda akan menambahkan item metadata lainnya, dengan menggunakan ekspresi kueri, jika blok metadata yang Anda padding mendukungnya. Contoh berikut menunjukkan cara menambahkan padding ke blok IFD yang disematkan di blok App1.

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

Untuk menambahkan padding, buat PROPVARIANT jenis VT_UI4 dan nilai yang sesuai dengan jumlah byte padding yang akan ditambahkan. Nilai umumnya adalah 4096 byte. Kueri metadata untuk JPEG, TIFF, dan JPEG-XR ada dalam tabel ini.

Format metadata Kueri metadata JPEG Kueri metadata TIFF, JPEG-XR
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

 

Mendapatkan Encoder Metadata Cepat

Ketika Anda memiliki gambar dengan padding metadata, encoder metadata cepat dapat diperoleh dengan menggunakan metode pabrik pencitraan CreateFastMetadataEncoderFromDecoder dan CreateFastMetadataEncoderFromFrameDecode.

Seperti namanya, CreateFastMetadataEncoderFromDecoder membuat encoder metadata cepat untuk metadata tingkat dekoder. Format gambar asli yang disediakan oleh WIC tidak mendukung metadata tingkat dekoder tetapi metode ini disediakan jika format gambar tersebut dikembangkan di masa mendatang.

Skenario yang lebih umum adalah mendapatkan encoder metadata cepat dari bingkai gambar dengan menggunakan CreateFastMetadataEncoderFromFrameDecode. Kode berikut mendapatkan encoder metadata cepat bingkai yang didekode dan mengubah nilai peringkat di blok App1.

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

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

Menggunakan Pengode Metadata Cepat

Dari encoder metadata cepat, Anda bisa mendapatkan penulis kueri. Ini memungkinkan Anda menulis metadata dengan menggunakan ekspresi kueri seperti yang ditunjukkan sebelumnya. Setelah metadata diatur di penulis kueri, terapkan encoder metadata cepat untuk menyelesaikan pembaruan metadata. Kode berikut menunjukkan pengaturan dan penerapan perubahan metadata

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

Jika Penerapan gagal karena alasan apa pun, Anda harus mengodekan ulang gambar untuk memastikan metadata baru ditambahkan ke gambar.

Konseptual

Gambaran Umum Komponen Pencitraan Windows

Gambaran Umum Metadata WIC

Gambaran Umum Bahasa Kueri Metadata

Gambaran Umum Ekstensibilitas Metadata

Cara: Mengodekan ulang Gambar JPEG dengan Metadata