Implementowanie IWICMetadataBlockReader
IWICMetadataBlockReader
Wiele bloków metadanych często istnieje w obrębie obrazu, z których każdy ujawnia różne typy informacji w różnych formatach. W modelu składnika Windows Imaging (WIC) programy obsługi metadanych są odrębnymi składnikami, które, takie jak dekodatory, są wykrywalne w czasie wykonywania. Każdy format metadanych ma oddzielną procedurę obsługi, a każdy z tych procedur obsługi metadanych może być używany z dowolnym formatem obrazu obsługującym obsługiwany format metadanych. W związku z tym jeśli format obrazu obsługuje format EXIF, XMP, IPTC lub inny format, możesz skorzystać ze standardowych procedur obsługi metadanych dla tych formatów, które są dostarczane z usługą WIC, i nie trzeba pisać własnych. Oczywiście, jeśli tworzysz nowy format metadanych, musisz napisać dla niego procedurę obsługi metadanych, która zostanie odnaleziona i wywołana w czasie wykonywania tak samo jak standardowe.
Notatka
Jeśli format obrazu jest oparty na kontenerze Tiff (Tagged Image File Format) lub JPEG, nie musisz pisać żadnych procedur obsługi metadanych (chyba że tworzysz nowy lub zastrzeżony format metadanych). W kontenerach TIFF i JPEG bloki metadanych znajdują się w plikach IFD, a każdy kontener ma inną strukturę IFD. WIC udostępnia programy obsługi IFD dla obu tych formatów kontenerów, które nawigują po strukturze IFD i delegują do standardowych procedur obsługi metadanych w celu uzyskania dostępu do metadanych w nich. Dlatego, jeśli format obrazu jest oparty na jednym z tych kontenerów, możesz automatycznie korzystać z modułów obsługi IFD WIC. Jeśli jednak masz zastrzeżony format kontenera, który ma własną unikatową strukturę metadanych najwyższego poziomu, musisz napisać procedurę obsługi, która może nawigować po tej strukturze najwyższego poziomu i delegować do odpowiednich procedur obsługi metadanych, podobnie jak programy obsługi IFD.
Tak samo jak WIC zapewnia warstwę abstrakcji dla aplikacji, które umożliwiają im pracę ze wszystkimi formatami obrazów w ten sam sposób za pośrednictwem spójnego zestawu interfejsów, WIC zapewnia warstwę abstrakcji dla autorów koderów w odniesieniu do formatów metadanych. Jak wspomniano wcześniej, autorzy koderów zwykle nie muszą pracować bezpośrednio z różnymi formatami metadanych, które mogą być obecne na obrazie. Jednak każdy autor kodeka jest odpowiedzialny za zapewnienie metody wyliczania bloków metadanych, dzięki czemu można odkryć i utworzyć przykład odpowiedniego programu obsługi metadanych dla każdego bloku.
Ten interfejs należy zaimplementować w klasie dekodowania na poziomie ramki. Może być również konieczne zaimplementowanie go w klasie dekodera na poziomie kontenera, jeśli format obrazu uwidacznia globalne metadane poza poszczególnymi ramkami obrazów.
interface IWICMetadataBlockReader : IUnknown
{
// All methods required
HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetCount ( UINT *pcCount );
HRESULT GetEnumerator ( IEnumUnknown **ppIEnumMetadata );
HRESULT GetReaderByIndex ( UINT nIndex, IWICMetadataReader **ppIMetadataReader );
}
PobierzFormatKontenera
GetContainerFormat jest taka sama jak metoda GetContainerFormat w Implementowaniu IWICBitmapDecoder.
PobierzLiczbę
getCount zwraca liczbę bloków metadanych najwyższego poziomu skojarzonych z ramką.
GetEnumerator
getEnumerator zwraca moduł wyliczający, za pomocą którego obiekt wywołujący może wyliczać bloki metadanych w ramce i odczytywać metadane. Aby zaimplementować tę metodę, należy utworzyć czytnik metadanych dla każdego bloku metadanych i zaimplementować obiekt, który wylicza kolekcję czytników metadanych. Obiekt wyliczenia musi implementować IEnumUnknown, aby można było rzutować go na IEnumUnknown podczas zwracania go w parametrze ppIEnumMetadata.
Podczas implementowania obiektu wyliczenia można utworzyć wszystkie czytniki metadanych podczas pierwszego tworzenia obiektu IWICMetadataBlockReader lub podczas pierwszego tworzenia obiektu wyliczenia, albo można je utworzyć dynamicznie wewnątrz implementacji metody IEnumUnknown::Next. W wielu przypadkach wydajniejsze jest tworzenie ich leniwie, ale w poniższym przykładzie czytniki bloków są tworzone w konstruktorze w celu zaoszczędzenia miejsca.
public class MetadataReaderEnumerator : public IEnumUnknown
{
UINT m_current;
UINT m_blockCount;
IWICMetadataReader** m_ppMetadataReader;
IStream* m_pStream;
MetadataReaderEnumerator()
{
// Set m_blockCount to the number of metadata blocks in the frame.
...
m_ppMetadataReader = IWICMetadataReader*[m_blockCount];
m_current = 0;
for (UINT x=0; x < m_blockCount; x++)
{
// Find the position in the file where the xth
// block of metadata lives and seek m_piStream
// to that position.
...
m_pComponentFactory->CreateMetadataReaderFromContainer(
GUID_ContainerFormatTiff,
NULL,
WICPersistOptions.WICPersistOptionsDefault |
WICMetadataCreationOptions.WICMetadataCreationDefault,
m_pStream, &m_ppMetadataReader[x]);
}
}
// Implementation of IEnumUnknown and IUnknown interfaces
...
}
Aby utworzyć czytniki metadanych, użyj metody CreateMetadataReaderFromContainer. Podczas wywoływania tej metody należy przekazać identyfikator GUID formatu kontenera w parametrze guidContainerFormat. Jeśli masz preferencję dostawcy dla czytnika metadanych, możesz przekazać identyfikator GUID preferowanego dostawcy w parametrze pGuidVendor. Jeśli na przykład firma zapisuje procedury obsługi metadanych i chcesz użyć własnych, jeśli istnieje, możesz przekazać identyfikator GUID dostawcy. W większości przypadków wystarczy przekazać NULLi pozwolić systemowi wybrać odpowiedni czytnik metadanych. Jeśli zażądasz określonego dostawcy, a ten dostawca ma na swoim komputerze zainstalowany czytnik metadanych, WIC zwróci czytnik tego dostawcy. Jeśli jednak żądany dostawca nie ma zainstalowanego czytnika metadanych na komputerze i jeśli jest dostępny odpowiedni czytnik metadanych, ten czytnik zostanie zwrócony, mimo że nie pochodzi z preferowanego dostawcy. Jeśli na komputerze nie ma czytnika dla danego typu metadanych zawartych w bloku, fabryka składników zwróci program obsługi nieznanych metadanych, który potraktuje blok metadanych jako binarny duży obiekt (BLOB) i zdeserializuje blok metadanych z pliku bez próby jego analizy.
W przypadku parametru dwOptions wykonaj operację OR między odpowiednim WICPersistOptions oraz odpowiednimi WICMetadataCreationOptions. WICPersistOptions opisują, jak rozmieszczony jest twój kontener. Little-endian jest wartością domyślną.
enum WICPersistOptions
{
WICPersistOptionDefault,
WICPersistOptionLittleEndian,
WICPersistOptionBigEndian,
WICPersistOptionStrictFormat,
WICPersistOptionNoCacheStream,
WICPersistOptionPreferUTF8
};
WICMetadataCreationOptions określają, czy chcesz otrzymać UnknownMetadataHandler, jeśli na maszynie nie znaleziono czytnika metadanych, który może odczytać format metadanych określonego bloku. WICMetadataCreationAllowUnknown jest wartością domyślną i zawsze należy zezwolić na utworzenie elementu UnknownMetadtataHandler. Funkcja UnknownMetadataHandler traktuje nierozpoznane metadane jako obiekt BLOB. Nie może go przeanalizować, ale zapisuje go w strumieniu jako obiekt BLOB i utrzymuje się bez zmian, gdy jest zapisywany z powrotem do strumienia podczas kodowania. Dzięki temu można bezpiecznie tworzyć programy obsługi metadanych dla zastrzeżonych formatów metadanych lub metadanych, które nie są dostarczane z systemem. Ponieważ metadane są zachowywane bez zmian, nawet jeśli program obsługi nie jest obecny na komputerze, który go rozpoznaje, gdy odpowiedni program obsługi metadanych zostanie zainstalowany później, metadane będą nadal dostępne i mogą być odczytywane. Jeśli nie zezwalasz na tworzenie UnknownMetadataHandler, alternatywą jest odrzucenie lub nadpisanie nierozpoznanych metadanych. Jest to forma utraty danych.
Notatka
Jeśli napiszesz własną procedurę obsługi metadanych dla zastrzeżonych metadanych, nigdy nie należy dołączać odwołań do niczego spoza samego bloku metadanych. Mimo że funkcja UnknownMetadataHandler zachowuje metadane nienaruszone, metadane są przenoszone, gdy pliki są edytowane, a wszelkie odwołania do niczego poza własnym blokiem nie będą już prawidłowe, gdy tak się stanie.
enum WICMetadataCreationOptions
{
WICMetadataCreationDefault = 0x00000000,
WICMetadataCreationAllowUnknown = WICMetadataCreationDefault,
WICMetadataCreationFailUnknown = 0x00010000,
WICMetadataCreationMask = 0xFFFF0000
};
Parametr pIStream jest rzeczywistym strumieniem, który dekodujesz. Zanim rozpoczniesz przetwarzanie strumienia, należy znaleźć początek bloku metadanych, dla którego żądasz odczytu. Odpowiedni czytnik metadanych dla bloku metadanych w bieżącym położeniu w IStream zostanie zwrócony w parametrze ppiReader.
GetReaderByIndex
Funkcja GetReaderByIndex zwraca czytnik metadanych na żądanym indeksie w kolekcji.
Tematy pokrewne
-
referencyjne
-
Koncepcyjny
-
Implementowanie IWICBitmapSourceTransform