Gambaran Umum Pembacaan dan Penulisan 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
- Pengenalan
- Membaca Metadadata Menggunakan Pembaca Kueri
- Menulis Metadata dengan Menggunakan Penulis Kueri
-
Pengodean Metadata Cepat
- Menambahkan Padding ke Blok Metadata
- Mendapatkan Encoder Metadata Cepat
- Menggunakan Pengenkode Metadata Cepat
- Topik terkait
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 .
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 handler 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 handler metadata untuk mengakses metadata yang dijelaskan oleh ekspresi kueri.
Metode yang lebih canggih adalah langsung mengakses handler metadata. Pengelola 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 berikut dari konten file gambar JPEG 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.
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).
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 WICDecodeOptions enumerasi. Ini memberi tahu dekoder untuk menyimpan metadata saat metadata diperlukan; baik dengan mendapatkan pembaca kueri maupun pembaca metadata yang mendasari. 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 milik bingkai tersebut. 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, berbeda dari pembaca kueri bingkai, membaca metadata untuk gambar yang berada di luar setiap bingkai. Namun, skenario ini tidak umum, dan format gambar asli tidak mendukung kemampuan ini. Metadata pada kodek gambar asli yang disediakan oleh WIC dibaca serta ditulis pada tingkat bingkai, bahkan untuk format bingkai tunggal seperti JPEG.
Sebelum Anda mulai benar-benar membaca metadata, lihat diagram file JPEG berikut yang menyertakan blok metadata yang disematkan dan data aktual untuk mengambil. Diagram ini menyediakan panggilan ke blok metadata dan item tertentu dalam gambar yang menyediakan ekspresi kueri metadata untuk setiap blok atau item.
Untuk mengkueri blok metadata yang disematkan atau item tertentu berdasarkan nama, panggil metode GetMetadataByName. Metode ini mengambil ekspresi kueri dan PROPVARIANT di mana item metadata dikembalikan. Kode berikut meminta blok metadata tersembunyi dan mengonversi komponen IUnknown yang diberikan oleh nilai PROPVARIANT menjadi 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. Berkas gambar JPEG berisi blok metadata IFD yang tertanam, sehingga PROPVARIANT dikembalikan dengan jenis variabel (vt) VT_UNKNOWN
dan pointer ke antarmuka IUnknown (punkVal). Anda kemudian menjalankan kueri pada 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}" adalah untuk meminta blok IFD mengenai peringkat MicrosoftPhoto yang disematkan di bawah tag 18249. Nilai PROPVARIANT sekarang akan berisi tipe nilai VT_UI2
dan nilai data 50.
Namun, tidak perlu mendapatkan blok berlapis sebelum mengkueri nilai data tertentu. Misalnya, alih-alih mengkueri IFD berlapis lalu 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 mendaftar item metadata di blok saat ini, metode GetEnumeration dari pembaca kueri digunakan. Metode ini memperoleh antarmuka IEnumString yang berisi 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.
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 menanyakan pembaca kueri yang disematkan tentang 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 tertanam ini mengembalikan GUID format metadata IFD. Panggilan ke GetLocation mengembalikan namespace "/app1/ifd", memberikan Anda jalur relatif dari mana 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.
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).
Penulis kueri yang paling umum adalah untuk bingkai tunggal dari bitmap. Penulis skrip kueri ini menetapkan dan menghapus blok dan item metadata bingkai gambar. Untuk mendapatkan penulis kueri bingkai gambar, panggil metode GetMetadataQueryWriter bingkai. Kode berikut menunjukkan pemanggilan metode sederhana untuk mendapatkan penulis kueri dari kerangka.
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 milik encoder menghasilkan 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 WIC membaca dan menulis metadata pada tingkat bingkai bahkan untuk format bingkai tunggal seperti JPEG.
Anda juga bisa mendapatkan penulis kueri langsung dari pabrik pencitraan (IWICImagingFactory). Ada dua metode pembuatan pencitraan yang menghasilkan 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 CreateQueryWriter untuk memanggil dan 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 ramah GUID_MetadataFormatXMP
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 dengan handler XMP asli, penerusan NULL untuk vendor akan menghasilkan pengembalian penulis kueri dengan GUID terendah.
CreateQueryWriterFromReader mirip dengan metode CreateQueryWriter kecuali bahwa metode ini sudah 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);
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 nilai jenisadalah string, pwszVal digunakan untuk mengatur judul yang akan digunakan.
SetMetadataByName kemudian dipanggil menggunakan ekspresi kueri "/dc:title" dan PROPVARIANTyang baru diatur. Ekspresi kueri yang digunakan menunjukkan bahwa properti judul pada skema kamera digital (dc) harus disetel. Perhatikan bahwa ekspresinya bukan "/xmp/dc:title"; ini karena penulis kueri sudah spesifik untuk XMP dan tidak mengandung blok XMP yang disematkan, yang akan diisyaratkan oleh "/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 blok metadata ke dalam bingkai yang diwakili oleh penulis kueri, Anda sekali lagi memanggil SetMetadataByName dengan menggunakan penulis kueri sebagai nilai dari 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, dengan menambahkan referensi terhadapnya menggunakan metode AddRef. Terakhir, penulis kueri XMP diatur dengan cara memanggil metode SetMetadataByName pada frame dan meneruskan ekspresi kueri "/", menunjukkan blok akar, serta PROPVARIANT yang baru ditetapkan.
Catatan
Jika bingkai sudah berisi blok metadata yang ingin Anda tambahkan, metadata baru akan ditambahkan dan metadata yang ada akan ditimpa.
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");
}
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; setiap operasi mengatur metadata bingkai yang didekodekan langsung ke dalam bingkai baru yang sedang dikodekan.
Metode yang diutamakan untuk menyalin metadata adalah dengan menginisialisasi penulis blok bingkai baru menggunakan pembaca blok bingkai yang telah didekode. 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 oleh pembaca blok. Ini menginisialisasi pembaca blok dengan metadata yang telah diisi sebelumnya dari pembaca blok.
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 dari bingkai yang sudah didekode dengan menggunakan metode CreateQueryWriterFromReader dari 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 penyalinan 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 yang dibuat berdasarkan data dari pembaca kueri. Penulis kueri baru ini kemudian ditempatkan di 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 disarangkan dalam blok IFD utama. Diagram berikut mengilustrasikan perbedaan antara gambar JPEG dan gambar TIFF dengan metadata peringkat yang sama.
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.
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 dalam 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 | Metadata JPEG kueri | TIFF, kueri metadata 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 |
Ketika Anda memiliki gambar dengan padding metadata, Anda dapat memperoleh encoder metadata cepat dengan menggunakan metode pada pabrik pencitraan CreateFastMetadataEncoderFromDecoder dan CreateFastMetadataEncoderFromFrameDecode.
Seperti namanya, CreateFastMetadataEncoderFromDecoder menciptakan encoder metadata cepat untuk metadata di tingkat dekoder. Format gambar asli yang disediakan oleh WIC tidak mendukung metadata tingkat dekoder tetapi metode ini disediakan jika format gambar seperti itu dikembangkan di masa depan.
Skenario yang lebih umum adalah mendapatkan encoder metadata cepat dari bingkai gambar dengan menggunakan CreateFastMetadataEncoderFromFrameDecode. Kode berikut mendapatkan encoder metadata cepat dari frame yang telah didekode dan mengubah nilai peringkat di blok App1.
if (SUCCEEDED(hr))
{
IWICFastMetadataEncoder *pFME = NULL;
IWICMetadataQueryWriter *pFMEQW = NULL;
hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
pFrameDecode,
&pFME);
}
Dari pengkode metadata yang 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 menerapkan 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 Commit gagal karena alasan apa pun, Anda harus mengodekan ulang gambar untuk memastikan metadata baru ditambahkan ke gambar.
-
Konseptual