Görüntü Meta Verilerini Okuma ve Yazma'ya Genel Bakış
Bu konu başlığında, görüntü dosyalarına eklenmiş meta verileri okumak ve yazmak için Windows Görüntüleme Bileşeni (WIC) API'lerini nasıl kullanabileceğinize ilişkin bir genel bakış sağlanır.
Bu konu aşağıdaki bölümleri içerir.
- Önkoşullar
- Giriş
- Meta Verileri Sorgu Okuyucusu Kullanarak Okuma
- Bir Sorgu Okuyucusu Edinme
- Meta Verileri okuma
- Ek Sorgu Okuyucu Yöntemleri
- Sorgu Yazıcı Kullanarak Meta Veri Yazma
- Hızlı Meta Veri Kodlama
- İlgili konular
Bu konuyu anlamak için, WIC Meta Verilerine Genel Bakışaçıklandığı gibi WIC meta veri sistemi hakkında bilgi sahibi olmanız gerekir. Meta Veri Sorgu Diline Genel Bakış açıklandığı gibi meta verileri okumak ve yazmak için kullanılan sorgu dilini de biliyor olmalısınız.
WIC, uygulama geliştiricilerine görüntü dosyalarına eklenmiş meta verileri okumak ve yazmak için Bileşen Nesne Modeli (COM) bileşenleri sağlar. Meta verileri okumanın ve yazmanın iki yolu vardır:
- İç içe bloklar veya bir blok içindeki belirli meta veriler için meta veri bloklarını sorgulamak amacıyla sorgu okuyucu/yazıcı ve sorgu ifadesi kullanma.
- meta veri blokları içinde iç içe meta veri bloklarına veya belirli meta verilere erişmek için bir meta veri işleyicisi (meta veri okuyucusu veya meta veri yazıcısı) kullanma.
Bunların en kolayı, meta verilere erişmek için sorgu okuyucu/yazıcı ve sorgu ifadesi kullanmaktır. Sorgu okuyucusu (IWICMetadataQueryReader) meta verileri okumak için kullanılırken, meta verileri yazmak için sorgu yazıcısı (IWICMetadataQueryWriter) kullanılır. Bunların her ikisi de istenen meta verileri okumak veya yazmak için bir sorgu ifadesi kullanır. Arka planda, sorgu okuyucusu (ve yazıcısı), sorgu ifadesi tarafından açıklanan meta verilere erişmek için bir meta veri işleyicisi kullanır.
Daha gelişmiş yöntem, meta veri işleyicilerine doğrudan erişmektir. Meta veri işleyicisi, blok okuyucu (IWICMetadataBlockReader) veya blok yazıcı (IWICMetadataBlockWriter) kullanılarak tek tek karelerden alınır. Kullanılabilir iki tür meta veri işleyicisi, meta veri okuyucu (IWICMetadataReader) ve meta veri yazıcıdır (IWICMetadataWriter).
Bir JPEG resim dosyasının içeriğinin aşağıdaki diyagramı, bu konudaki örnekler boyunca kullanılır. Bu diyagram tarafından temsil edilen görüntü Microsoft Paint kullanılarak oluşturulmuştur; derecelendirme meta verileri, Windows Vista'nın Fotoğraf Galerisi özelliği kullanılarak eklenmiştir.
Derecelendirme meta verilerine sahip jpeg görüntüsünün
Meta verileri okumanın en kolay yolu, IWICMetadataQueryReadersorgu okuyucu arabirimini kullanmaktır. Sorgu okuyucu, bir sorgu ifadesi kullanarak meta veri blokları ve meta veri blokları içindeki öğeleri okumanızı sağlar.
Sorgu okuyucu edinmenin üç yolu vardır: bit eşlem kod çözücüsü aracılığıyla (IWICBitmapDecoder), tek tek çerçeveleri aracılığıyla (IWICBitmapFrameDecode) veya sorgu yazıcısı aracılığıyla (IWICMetadataQueryWriter).
Aşağıdaki örnek kod, görüntüleme fabrikasından bir bit eşlem kod çözücü elde etme ve tek bir bit eşlem çerçevesi alma işlemini gösterir. Bu kod, kodu çözülen bir çerçeveden sorgu okuyucu elde etmek için gereken kurulum çalışmalarını da gerçekleştirir.
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);
}
test.jpg dosyasının bit eşlem kod çözücüsü, görüntüleme fabrikasının CreateDecoderFromFilename yöntemi kullanılarak elde edilir. Bu yöntemde dördüncü parametre, WICDecodeOptions numaralandırmasından WICDecodeMetadataCacheOnDemand değerine ayarlanır. Bu, kod çözücüye meta veriler gerektiğinde meta verileri önbelleğe almasını belirtir; ya bir sorgu okuyucu alarak ya da temel meta veri okuyucusunu kullanarak. Bu seçeneğin kullanılması, hızlı meta veri kodlaması için gereken meta veriler için akışı korumanıza ve JPEG görüntüsünün kayıpsız kod çözmesine olanak tanır. Alternatif olarak, görüntü yüklendiğinde gömülü görüntü meta verilerini önbelleğe alan WICDecodeMetadataCacheOnLoad değerini içeren diğer WICDecodeOptions seçeneğini kullanabilirsiniz.
Çerçevenin GetMetadataQueryReader yöntemine basit bir çağrı yaparak çerçevenin sorgu okuyucusunu alın. Aşağıdaki kod bu çağrıyı gösterir.
// Get the query reader
if (SUCCEEDED(hr))
{
hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}
Benzer şekilde, bir sorgu okuyucu da kod çözücü düzeyinde elde edilebilir. Kod çözücüsü GetMetadataQueryReader yöntemine yapılan basit bir çağrı, kod çözücüsü sorgu okuyucusunu alır. Kod çözücülerin sorgu okuyucusu, çerçevenin sorgu okuyucusunun aksine, tek tek çerçevelerin dışındaki bir görüntünün meta verilerini okur. Ancak bu senaryo yaygın değildir ve yerel görüntü biçimleri bu özelliği desteklemez. WIC tarafından sağlanan yerel görüntü CODEC'leri JPEG gibi tek kareli biçimler için bile çerçeve düzeyinde meta verileri okur ve yazar.
Gerçekten meta verileri okumaya geçmeden önce, ekli meta veri bloklarını ve alınacak gerçek verileri içeren jpeg dosyasının aşağıdaki diyagramına bakın. Bu diyagram, görüntüdeki belirli meta veri blokları ve öğelere açıklamalar sağlar ve her bir blok veya öğeye yönelik meta veri sorgu ifadesini sunar.
Jpeg görüntüsünün, meta veri açıklama balonlarıyla birlikte çizimi
Ekli meta veri bloklarını veya belirli öğeleri ada göre sorgulamak için GetMetadataByName yöntemini çağırın. Bu yöntem bir sorgu ifadesi ve meta veri öğesinin geri döndürüldüğü PROPVARIANT alır. Aşağıdaki kod iç içe meta veri bloğunu sorgular ve bulunursa PROPVARIANT değeri tarafından sağlanan IUnknown bileşenini sorgu okuyucuya dönüştürür.
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
}
"/app1/ifd" sorgu ifadesi, App1 bloğunda iç içe yerleştirilmiş IFD bloğunu sorgular. JPEG görüntü dosyası, IFD iç içe meta veri bloğunu içerdiğinden, sonuç olarak PROPVARIANTVT_UNKNOWN
değişken türü (vt) ve IUnknown arabirimi (punkVal) işaretçisi ile geri döndürülür. Ardından bir sorgu okuyucu için IUnknown arabirimini sorgularsınız.
Aşağıdaki kod, iç içe yerleştirilmiş IFD bloğuna göre yeni sorgu okuyucuyu temel alan yeni bir sorguyu gösterir.
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetMetadataByName(L"/{ushort=18249}", &value);
PropVariantClear(&value); // Clear value for new query
}
"/{ushort=18249}" sorgu ifadesi, 18249 etiketine eklenmiş MicrosoftPhoto derecelendirmesi için IFD bloğunu sorgular.
PROPVARIANT değeri artık VT_UI2
değer türünü ve 50 veri değerini içerir.
Ancak, belirli veri değerlerini sorgulamadan önce iç içe bir blok elde etmek gerekli değildir. Örneğin, iç içe IFD ve ardından MicrosoftPhoto derecelendirmesi için sorgulama yapmak yerine, aynı bilgileri almak için kök meta veri bloğunu ve aşağıdaki kodda gösterilen sorguyu kullanabilirsiniz.
if (SUCCEEDED(hr))
{
hr = pQueryReader->GetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);
PropVariantClear(&value);
}
Meta veri bloğundaki belirli meta veri öğelerini sorgulamaya ek olarak, meta veri bloğundaki tüm meta veri öğelerini de numaralandırabilirsiniz (iç içe meta veri bloklarındaki meta veri öğeleri dahil değildir). Geçerli bloktaki meta veri öğelerini numaralandırmak için sorgu okuyucusunun GetEnumeration yöntemi kullanılır. Bu yöntem, geçerli bloktaki meta veri öğeleriyle doldurulmuş bir IEnumString arabirimi alır. Örneğin, aşağıdaki kod daha önce elde edilen iç içe yerleştirilmiş IFD bloğu için XMP derecelendirmesini ve MicrosoftPhoto derecelendirmesini numaralandırır.
IEnumString *metadataItems = NULL;
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetEnumerator(&metadataItems);
}
Çeşitli görüntü biçimleri ve meta veri biçimleri için uygun etiketleri tanımlama hakkında daha fazla bilgi için bkz. Yerel Görüntü Biçimi Meta Veri Sorguları.
Meta verileri okumanın yanı sıra, sorgu okuyucusu hakkında ek bilgi edinebilir ve meta verileri başka yollarla alabilirsiniz. Sorgu okuyucu, sorgu okuyucusu hakkında bilgi sağlayan iki yöntem sunar: GetContainerFormat ve GetLocation.
Eklenmiş sorgu okuyucu ile, meta veri bloğunun türünü belirlemek için GetContainerFormat kullanabilir ve kök meta veri bloğuna göre yolu elde etmek için GetLocation çağırabilirsiniz. Aşağıdaki kod, eklenmiş sorgu okuyucuyu konumu için sorgular.
// 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);
}
Gömülü sorgu okuyucusu için GetContainerFormat çağrısı, IFD meta veri biçimi GUID'sini geri döndürür. GetLocation çağrısı, "/app1/ifd" ad alanını döndürür ve bu, yeni sorgu okuyucusuna yapılacak sonraki sorguların çalıştırılacağı göreli yolu sağlar. Tabii ki, önceki kod çok kullanışlı değildir, ancak iç içe meta veri bloklarını bulmak için GetLocation yönteminin nasıl kullanılacağını gösterir.
Not
Bu bölümde sağlanan kod örneklerinden bazıları, meta veri yazmak için gereken gerçek adımlar bağlamında gösterilmez. Çalışan örnek bağlamındaki kod örneklerini görüntülemek için Nasıl yapılır: Meta Verilerle Görüntüyü Yeniden Kodlama öğreticisine bakın.
Meta veri yazmanın ana bileşeni sorgu yazıcıdır (IWICMetadataQueryWriter). Sorgu yazıcı, meta veri bloğu içindeki meta veri bloklarını ve öğeleri ayarlamanıza ve kaldırmanıza olanak tanır.
Sorgu okuyucusu gibi, bir sorgu yazıcısı elde etmenin üç yolu vardır: bit eşlem kodlayıcı aracılığıyla (IWICBitmapEncoder), tek tek çerçeveleri aracılığıyla (IWICBitmapFrameEncode) veya hızlı meta veri kodlayıcı aracılığıyla (IWICFastMetadataEncoder).
En yaygın sorgu yazıcı, bir bit eşleminin tek bir karesi içindir. Bu sorgu yazıcı, görüntü çerçevesinin meta veri bloklarını ve öğelerini ayarlar ve kaldırır. Görüntü çerçevesinin sorgu yazıcısını almak için çerçevenin GetMetadataQueryWriter yöntemini çağırın. Aşağıdaki kod, çerçevenin sorgu yazıcısını almak için basit yöntem çağrısını gösterir.
IWICMetadataQueryWriter &pFrameQWriter = NULL;
//Obtain a query writer from the frame.
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
Benzer şekilde, kodlayıcı düzeyi için bir sorgu yazıcı da elde edilebilir. Kodlayıcının GetMetadataQueryWriter yöntemine yapılan basit bir çağrı, kodlayıcının sorgu yazıcısını alır. Bir kodlayıcının sorgu yazıcısı, bir çerçevenin sorgu yazıcısından farklı olarak, bireysel çerçeve dışında bir resim için meta veriler yazar. Ancak bu senaryo yaygın değildir ve yerel görüntü biçimleri bu özelliği desteklemez. WIC tarafından sağlanan yerel görüntü codec'leri JPEG gibi tek kareli biçimler için bile çerçeve düzeyinde meta verileri okur ve yazar.
Görüntüleme fabrikasından doğrudan bir sorgu yazıcısı da alabilirsiniz (IWICImagingFactory). Sorgu yazıcısı döndüren iki görüntüleme fabrikası yöntemi vardır: CreateQueryWriter ve CreateQueryWriterFromReader.
CreateQueryWriter, belirtilen meta veri biçimi ve satıcı için bir sorgu yazıcı oluşturur. Bu sorgu yazıcı, belirli bir meta veri biçimi için meta veriler yazmanızı ve resme eklemenizi sağlar. Aşağıdaki kod, XMP sorgu yazıcısı oluşturmak için CreateQueryWriter çağrısını gösterir.
IWICMetadataQueryWriter *pXMPWriter = NULL;
// Create XMP block
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriter(
GUID_MetadataFormatXMP,
&vendor,
&pXMPWriter);
Bu örnekte, kullanıcı dostu ad GUID_MetadataFormatXMP
, guidMetadataFormat parametresi olarak kullanılır. XMP meta veri biçimi GUID'sini, satıcı ise Microsoft tarafından oluşturulan işleyiciyi temsil eder. Alternatif olarak, NULL, başka bir XMP işleyicisi yoksa aynı sonuçlara sahip pguidVendor parametresi olarak geçirilebilir. Yerel XMP işleyicisi ile birlikte özel bir XMP işleyicisi yüklenirse, satıcıya NULL geçirildiğinde en düşük GUID'e sahip sorgu yazarı döndürülür.
CreateQueryWriterFromReader, yeni sorgu yazıcısını sorgu okuyucusu tarafından sağlanan verilerle önceden doldurması dışında CreateQueryWriter yöntemine benzer. Bu, mevcut meta verileri korurken bir görüntüyü yeniden kodlamak veya istenmeyen meta verileri kaldırmak için kullanışlıdır. Aşağıdaki kod bir CreateQueryWriterFromReader çağrısını gösterir.
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);
Sorgu yazıcısını aldıktan sonra meta veri blokları ve öğeler eklemek için bunu kullanabilirsiniz. Meta veri yazmak için sorgu yazıcısının SetMetadataByName yöntemini kullanırsınız. SetMetadataByName iki parametre alır: sorgu ifadesi (wzName) ve PROPVARIANT işaretçisi (pvarValue). Sorgu ifadesi, ayarlanacak bloğu veya öğeyi tanımlarken, PROPVARIANT ayarlanacak gerçek veri değerini sağlar.
Aşağıdaki örnekte, daha önce CreateQueryWriter yöntemi kullanılarak elde edilen XMP sorgu yazıcısını kullanarak başlık ekleme işlemi gösterilmektedir.
// 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);
}
Bu örnekte değerin türü (vt) VT_LPWSTR
olarak ayarlanmıştır ve bu da veri değeri olarak bir dizenin kullanılacağını gösterir.
değeritüründe bir dize olduğundan, kullanılacak başlığı ayarlamak için pwszVal kullanılır.
SetMetadataByName daha sonra "/dc:title" sorgu ifadesi ve yeni ayarlanan PROPVARIANTkullanılarak çağrılır. Kullanılan sorgu ifadesi, dijital kamera (dc) şemasındaki title özelliğinin ayarlanması gerektiğini belirtir. İfadenin "/xmp/dc:title" olmadığını unutmayın; çünkü sorgu yazıcısı zaten XMP'ye özgüdür ve "/xmp/dc:title" ifadesinin ima ettiği gibi içinde bir XMP bloğu barındırmaz.
Bu noktaya kadar bir görüntü çerçevesine hiç meta veri eklememişsinizdir. Bir sorgu yazıcıyı verilerle doldurmanız yeterlidir. Çerçeveye sorgu yazıcısı tarafından temsil edilen bir meta veri bloğu eklemek için, sorgu yazıcısını PROPVARIANTdeğeri olarak kullanarak SetMetadataByName yeniden çağırırsınız. Bu, sorgu yazıcıdaki meta verileri etkili bir şekilde görüntü çerçevesine kopyalar. Aşağıdaki kod, daha önce bir çerçevenin kök meta veri bloğuna elde edilen XMP sorgu yazıcısında meta verilerin nasıl ekleneceğini gösterir.
// 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);
}
}
Bu örnekte, VT_UNKOWN
değer türü (vt) kullanılır; com arabirimi değer türünü belirtir. Daha sonra XMP sorgu yazıcısı (piXMPWriter), AddRef yöntemi kullanılarak başvuru eklenerek PROPVARIANTdeğeri olarak kullanılır. Son olarak, XMP sorgu yazıcısı, çerçevenin SetMetadataByName yöntemi çağrılarak ve kök bloğu temsil eden ve yeni ayarlanan PROPVARIANT'ı içeren "/" sorgu ifadesi kullanılarak ayarlanır.
Not
Çerçeve, eklemeye çalıştığınız meta veri bloğunu zaten içeriyorsa, eklediğiniz meta veriler eklenir ve mevcut meta verilerin üzerine yazılır.
Sorgu yazıcısı ayrıca RemoveMetadataByName yöntemini çağırarak meta verileri kaldırmanıza da olanak tanır. RemoveMetadataByName bir sorgu ifadesi alır ve varsa meta veri bloğunu veya öğeyi kaldırır. Aşağıdaki kod, daha önce eklenmiş olan başlığın nasıl kaldırılacağını gösterir.
if (SUCCEEDED(hr))
{
hr = pFrameQWriter->RemoveMetadataByName(L"/xmp/dc:title");
}
Aşağıdaki kod, XMP meta veri bloğunun tamamının nasıl kaldırılacağını gösterir.
if (SUCCEEDED(hr))
{
hr = pFrameQWriter->RemoveMetadataByName(L"/xmp");
}
Not
Bu bölümdeki kod yalnızca kaynak ve hedef görüntü biçimleri aynı olduğunda geçerlidir. Farklı bir görüntü biçimine kodlama yaparken görüntünün tüm meta verilerini tek bir işlemde kopyalayamazsınız.
Bir görüntüyü aynı görüntü biçimine yeniden kodlarken meta verileri korumak için tüm meta verileri tek bir işlemde kopyalamak için kullanabileceğiniz yöntemler vardır. Bu işlemlerin her biri benzer bir desen izler; her biri kodu çözülen çerçevenin meta verilerini doğrudan kodlanan yeni çerçeveye ayarlar.
Meta verileri kopyalamak için tercih edilen yöntem, yeni çerçevenin blok yazıcısını kodu çözülen çerçevenin blok okuyucusuyla başlatmaktır. Aşağıdaki kod bu yöntemi gösterir.
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);
}
}
Bu örnekte, blok okuyucu ve blok yazıcı sırasıyla kaynak çerçeveden ve hedef çerçeveden alınır. Blok yazıcı daha sonra blok okuyucudan başlatılır. Bu, blok okuyucuyu blok okuyucunun önceden doldurulmuş meta verileriyle başlatır.
Meta verileri kopyalamanın başka bir yöntemi de kodlayıcının sorgu yazıcısını kullanarak sorgu okuyucusu tarafından başvurulan meta veri bloğunu yazmaktır. Aşağıdaki kod bu yöntemi gösterir.
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);
}
}
}
Burada, kodu çözülen çerçeveden bir sorgu okuyucu alınır ve ardından değer türü VT_UNKNOWN olarak ayarlanmış PROPVARIANT özellik değeri olarak kullanılır. Kodlayıcı için sorgu yazıcısı alınır ve kök gezinti yolunda meta verileri ayarlamak için "/" sorgu ifadesi kullanılır. Sorgu ifadesini istenen konuma ayarlayarak iç içe meta veri bloklarını ayarlarken de bu yöntemi kullanabilirsiniz.
Benzer şekilde, görüntüleme fabrikasının CreateQueryWriterFromReader yöntemini kullanarak kodu çözülen çerçevenin sorgu okuyucusunu temel alan bir sorgu yazıcı oluşturabilirsiniz. Bu işlemde oluşturulan sorgu yazıcısı, sorgu okuyucusunun meta verileriyle önceden doldurulur ve ardından çerçevede ayarlanabilir. Aşağıdaki kodda CreateQueryWriterFromReader kopyalama işlemi gösterilmektedir.
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);
}
Bu yöntem, sorgu okuyucu verilerini temel alan ayrı bir sorgu yazıcısı oluşturur. Bu yeni sorgu yazıcı daha sonra çerçeveye yerleştirildi.
Meta verileri kopyalamaya yönelik bu işlemler, yalnızca kaynak ve hedef görüntüler aynı biçime sahip olduğunda çalışır. Bunun nedeni, farklı görüntü biçimlerinin meta veri bloklarını farklı konumlarda depolamasıdır. Örneğin, hem JPEG hem de TIFF XMP meta veri bloklarını destekler. JPEG görüntülerinde XMP bloğu, WIC Meta Verilerine Genel Bakışgösterildiği gibi kök meta veri bloğundadır. Ancak, BIR TIFF görüntüsünde, XMP bloğu bir kök IFD bloğunda iç içe yerleştirilmiştir. Aşağıdaki diyagramda JPEG görüntüsü ile aynı derecelendirme meta verilerine sahip bir TIFF görüntüsü arasındaki farklar gösterilmektedir.
jpeg ve tiff karşılaştırması .
Yeni meta veriler yazmak için bir görüntüyü yeniden kodlamak her zaman gerekli değildir. Meta veriler, hızlı bir meta veri kodlayıcı kullanılarak da yazılabilir. Hızlı meta veri kodlayıcı, görüntüyü yeniden kodlamadan görüntüye sınırlı miktarda meta veri yazabilir. Bu, bazı meta veri biçimleri tarafından sağlanan boş doldurma içinde yeni meta veriler yazılarak gerçekleştirilir. Meta veri doldurmayı destekleyen yerel meta veri biçimleri Exif, IFD, GPS ve XMP'dir.
Hızlı meta veri kodlaması yapabilmeniz için önce meta veri bloğunun içinde daha fazla meta veri yazmak için yer olmalıdır. Mevcut doldurmada yeni meta verileri yazmak için yeterli alan yoksa hızlı meta veri kodlaması başarısız olur. Görüntüye meta veri doldurma eklemek için görüntünün yeniden kodlanması gerekir. Eğer doldurduğunuz meta veri bloğu destekliyorsa, herhangi bir başka meta veri öğesi ekler gibi, sorgu ifadesi kullanarak dolgu ekleyebilirsiniz. Aşağıdaki örnek, App1 bloğuna gömülmüş bir IFD bloğuna nasıl boşluk eklenebileceğini göstermektedir.
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);
}
Doldurma eklemek için, VT_UI4 türünde bir PROPVARIANT ve eklenecek doldurma bayt sayısına karşılık gelen bir değer oluşturun. Tipik bir değer 4096 bayttır. JPEG, TIFF ve JPEG-XR için meta veri sorguları bu tabloda yer alır.
Meta veri biçimi | JPEG meta veri sorgusu | TIFF, JPEG-XR meta veri sorgusu |
---|---|---|
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/DolguŞeması:Dolgu |
Meta verisi dolgu olan bir görüntüye sahip olduğunuzda, CreateFastMetadataEncoderFromDecoder ve CreateFastMetadataEncoderFromFrameDecodegörüntüleme fabrikası yöntemlerini kullanarak hızlı bir meta veri kodlayıcı elde edilebilir.
Adından da anlaşılacağı gibi CreateFastMetadataEncoderFromDecoder kod çözücü düzeyinde meta veriler için hızlı bir meta veri kodlayıcı oluşturur. WIC tarafından sağlanan yerel görüntü biçimleri kod çözücü düzeyinde meta verileri desteklemez, ancak gelecekte böyle bir görüntü biçiminin geliştirilmesi durumunda bu yöntem sağlanır.
Daha yaygın senaryo, CreateFastMetadataEncoderFromFrameDecodekullanarak bir görüntü çerçevesinden hızlı meta veri kodlayıcı elde etmektir. Aşağıdaki kod, kodu çözülen bir çerçevenin hızlı meta veri kodlayıcısını alır ve App1 bloğundaki derecelendirme değerini değiştirir.
if (SUCCEEDED(hr))
{
IWICFastMetadataEncoder *pFME = NULL;
IWICMetadataQueryWriter *pFMEQW = NULL;
hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
pFrameDecode,
&pFME);
}
Hızlı meta veri kodlayıcıdan bir sorgu yazıcısı alabilirsiniz. Bu, daha önce gösterildiği gibi bir sorgu ifadesi kullanarak meta veri yazmanızı sağlar. Sorgu yazıcısında meta veriler ayarlandıktan sonra, meta veri güncelleştirmesini sonlandırmak için hızlı meta veri kodlayıcısını tamamlayın. Aşağıdaki kod, meta veri değişikliklerini ayarlamayı ve işlemeyi gösterir
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();
}
}
Commit herhangi bir nedenle başarısız olursa, görüntüye yeni meta verilerin eklendiğinden emin olmak için görüntüyü yeniden kodlamanız gerekir.
-
kavramsal
-
Nasıl Yapılır: Meta Veri ile JPEG Görüntüsünü Yeniden Kodlama