Wie Sie einen WIC-fähigen CODEC schreiben und vollständige Plattformunterstützung für Ihr Bildformat erhalten

Veröffentlicht: 20. Nov 2006

WIC (Windows Imaging Component) ist eine erweiterbare Plattform für die digitale Bildverarbeitung unter Windows Vista. Sie steht als Teil des .NET Framework 3.0 oder als separate verteilbare Komponente auch unter Windows XP und Windows Server 2003 zur Verfügung. WIC führt eine Abstraktionsschicht zwischen Anwendungen und CODECs ein, so dass die Notwendigkeit für Anwendungen entfällt, spezielle Kenntnisse über bestimmte Bildformate zu besitzen. Jede Anwendung, die die Windows Imaging Component einsetzt, kann unter Verwendung einer einzigen Menge konsistenter Schnittstellen auf Bilder zugreifen, sie anzeigen, verarbeiten, speichern und drucken. Dies alles ist unabhängig vom Bildformat möglich, wenn ein WIC-fähiger CODEC für das Bildformat auf dem Computer installiert ist.

Der Windows Vista Explorer, die Fotogalerie und die Bildanzeige basieren auf WIC. Nachdem also ein WIC-fähiger CODEC auf einem Windows Vista-System installiert ist, bietet Windows Vista für das zugeordnete Bildformat dasselbe Maß an Unterstützung wie für die zusammen mit der Plattform bereitgestellten Standardbildformate. Weil Sie den CODEC für Ihr eigenes Bildformat selbst schreiben, können Sie für jeden Einsatzzweck Ihres Bildformats eine konsistente Qualität sicherstellen. Sie genießen die Vorteile der vollständigen Plattformunterstützung, während Sie gleichzeitig Ihre IP-Investitionen schützen. (45 gedruckte Seiten)

Auf dieser Seite

Die Arbeitsweise der Windows Imaging Component Die Arbeitsweise der Windows Imaging Component
Einen WIC-fähigen Decoder implementieren Einen WIC-fähigen Decoder implementieren
Einen WIC-fähigen Encoder implementieren Einen WIC-fähigen Encoder implementieren
Installation und Registrierung von CODECs Installation und Registrierung von CODECs
Schlussbemerkung Schlussbemerkung

Die Arbeitsweise der Windows Imaging Component

Erkennen und Verteilen

Damit ein Bild decodiert werden kann, muss ein geeigneter CODEC gefunden werden, der das verwendete Bildformat decodieren kann. In den meisten Systemen sind die unterstützten Bildformate fest codiert, so dass kein Erkennungsprozess erforderlich ist. Weil die WIC-Plattform erweiterbar ist, muss man in der Lage sein, das Format eines Bildes zu identifizieren und es einem geeigneten CODEC zuzuordnen.

Um eine Laufzeiterkennung zu unterstützen, muss jedes Bildformat ein Erkennungsmuster besitzen, anhand dessen ein geeigneter Decoder für dieses Format identifiziert werden kann. (Wir empfehlen Ihnen dringend, bei neuen Dateiformaten eine GUID als Erkennungsmuster zu verwenden, weil diese garantiert eindeutig ist.) Das Erkennungsmuster muss in jede Bilddatei eingebettet sein, die diesem Bildformat entspricht. Für jeden Decoder gibt es einen Registrierungseintrag, der die Erkennungsmuster aller Bildformate enthält, die der Decoder decodieren kann. Muss eine Anwendung ein Bild öffnen, fordert sie einen Decoder von der WIC an. Die WIC sucht in der Registrierung nach den verfügbaren Decodern und überprüft jeden Registrierungseintrag auf ein Erkennungsmuster, das mit dem in die Bilddatei eingebetteten Muster übereinstimmt. Weitere Informationen darüber finden Sie im Abschnitt Decoder-spezifische Registrierungseinträge.

Findet die WIC nur einen einzigen Decoder, der mit dem Erkennungsmuster im Bild übereinstimmt, instantiiert sie den Decoder und übergibt ihm die Bilddatei. Findet die WIC mehrere Übereinstimmungen, ruft sie eine Methode namens QueryCapability für jeden übereinstimmenden Decoder auf, um zwischen ihnen zu wählen und die beste Übereinstimmung zu finden. Genauere Informationen darüber finden Sie im Abschnitt über die Methode QueryCapability der Schnittstelle IWICBitmapDecoder.

Hinweis   Nur signierte CODECs können am Erkennungsprozess der WIC teilnehmen.

Decodieren

Nachdem ein geeigneter Decoder ausgewählt und instantiiert wurde, kommuniziert die Anwendung direkt mit dem Decoder. Der Decoder hat verschiedene Aufgaben, die er über verschiedene Schnittstellen implementiert. Diese Dienste können wie folgt eingeordnet werden:

  • Dienste auf Container-Ebene

  • Dienste auf Frame-Ebene

  • Dienste für die Auflistung von Metadaten

  • Systemeigene Decoder-Transformationen

  • Fortschrittsbenachrichtigungen und Abbruch-Unterstützung

  • Rohdaten-Verarbeitungsdienste

Dienste auf Container-Ebene beinhalten das Laden der Miniaturansicht für die oberste Ebene (falls unterstützt), der Vorschau, der Farbkontexte, der Palette (falls zutreffend) und des Container-Formats, und sie bieten Zugriff auf die einzelnen Bild-Frames innerhalb des Containers. (Einige Container enthalten nur einen einzigen Frame, während andere, wie etwa TIFF, mehrere Frames enthalten können.) Diese Dienstmenge beinhaltet auch die Bereitstellung von Informationen über den eigentlichen Decoder sowie die von ihm für eine bestimmte Bilddatei unterstützten Funktionen.

Einzelne Frames haben ihre eigenen Miniaturansichten und können auch eigene Farbkontexte, Paletten usw. haben, die auf Frame-Ebene bereitgestellt werden. Die wichtigste Operation auf der Frame-Ebene ist jedoch die eigentliche Decodierung der Bild-Bits für diesen Frame.

WIC stellt Metadaten-Leser für die gebräuchlichsten Metadaten-Formate (IFD, EXIF, IPTC, XMP, APP0, APP1 usw.) bereit und ist außerdem für Metadaten-Formate von Drittanbietern erweiterbar. Das befreit den CODEC von der Aufgabe, Metadaten zu analysieren, aber er ist dafür verantwortlich, die Metadaten-Blöcke aufzulisten und für jeden Block einen Metadaten-Leser anzufordern. Die Erkennung für Metadaten-Handler führt WIC auf dieselbe Weise wie für CODECs durch, und zwar basierend auf einem Muster im Block-Header, das mit einem Muster im Registrierungseintrag für den Metadaten-Handler übereinstimmen muss. Weitere Informationen darüber finden Sie im Abschnitt Decoder-spezifische Registrierungseinträge unter dem Punkt Installation und Registrierung eines CODECs.

Decoder müssen keine systemeigene Unterstützung von Transformationsoperationen bieten, aber wenn sie das tun, ist damit eine wesentliche Leistungsoptimierung möglich, die eine bessere Endbenutzererfahrung zulässt. Beispielsweise kann eine Anwendung eine Pipeline verschiedener Transformationen anlegen (Skalieren, Zuschneiden, Drehen, Pixelformatumwandlung), die auf ein Bild angewendet werden, bevor es dargestellt wird. (Weitere Informationen über Transformations-Pipelines finden Sie im Abschnitt über IWICBitmapSource.) Nachdem eine Transformations-Pipeline angelegt wurde, fordert die Anwendung die letzte Transformation in der Pipeline auf, die Bitmap zu erzeugen, die aus der Anwendung aller Transformationen auf die Bildquelle entsteht. Falls der Decoder zu diesem Zeitpunkt selbst in der Lage ist, Transformationsoperationen auszuführen, fragt die WIC bei ihm nach, welche der angeforderten Transformationen er ausführen kann. Falls der Decoder angeforderte Transformationen nicht ausführen kann, werden diese von der WIC für das decodierte Bild ausgeführt, bevor es an den Aufrufer zurückgegeben wird. Diese optimierte Transformations-Pipeline bietet eine bessere Leistung als die sequentielle Durchführung jeder einzelnen Transformation im Speicher, insbesondere wenn einige oder ein Teil der Transformationen während des Decodierungsprozesses durchgeführt werden können.

Rohdaten-Verarbeitungsdienste beinhalten die Anpassung von Kameraeinstellungen, wie beispielsweise Belichtung, Kontrast, Schärfe usw., oder die Änderung des Farbraums vor Verarbeitung der Rohdaten-Bits.

Fortschrittsbenachrichtigungen und die Abbruch-Unterstützung ermöglichen einer Anwendung, Fortschrittsbenachrichtigungen für lang andauernde Operationen anzufordern und dem Benutzer eine Möglichkeit zu bieten, eine Operation abzubrechen, die zu lange dauert. Das ist wichtig, denn wenn ein Benutzer eine Operation nicht abbrechen kann, hat er vielleicht den Eindruck, der Prozess wäre abgestürzt, und er versucht, ihn abzubrechen, indem er die Anwendung schließt.

Diese Schnittstellen sind detailliert im Abschnitt Einen WIC-fähigen Decoder implementieren beschrieben.

Codieren

Wie Decoder haben auch Encoder Aufgaben, die sie über verschiedene Schnittstellen implementieren. Die von den Encodern bereitgestellten Dienste ergänzen die von den Decodern bereitgestellten Dienste, schreiben aber die Bilddaten, statt sie zu lesen. Encoder bieten ebenfalls Dienste in den folgenden Kategorien an:

  • Dienste auf Container-Ebene

  • Dienste auf Frame-Ebene

  • Dienste für die Auflistung und Aktualisierung von Metadaten

  • Fortschrittsbenachrichtigungen und Abbruch-Unterstützung

Dienste auf Container-Ebene für einen Encoder beinhalten die Festlegung der Miniaturansicht für die oberste Ebene (falls unterstützt), der Vorschau und der Palette (falls zutreffend) sowie das Durchlaufen der einzelnen Bild-Frames, so dass sie im Container serialisiert werden können.

Dienste auf der Frame-Ebene für den Encoder sind vergleichbar mit denjenigen für den Decoder, außer dass sie die Bilddaten, die Miniaturansicht und gegebenenfalls zugeordnete Paletten usw. schreiben, statt sie zu lesen.

Analog dazu beinhalten die Dienste für die Auflistung von Metadaten bei einem Encoder das Durchlaufen der zu schreibenden Metadaten-Blöcke und den Aufruf der geeigneten Metadaten-Schreiber, um die Metadaten auf die Festplatte zu serialisieren.

Diese Schnittstellen sind im Abschnitt Einen WIC-fähigen Encoder implementieren genauer beschrieben.

Lebensdauer eines CODECs

Ein WIC CODEC wird instantiiert, um ein einziges Bild zu verarbeiten, und hat in der Regel eine kurze Lebensdauer. Er wird erzeugt, wenn ein Bild geladen wird, und freigegeben, sobald das Bild geschlossen wird. Eine Anwendung kann eine große Anzahl von CODECs gleichzeitig verwenden, deren Lebensdauern sich überlappen (stellen Sie sich beispielsweise vor, dass ein Verzeichnis mit Hunderten von Bildern durchlaufen wird), und mehrere Anwendungen können die CODECs gleichzeitig anfordern.

Möglicherweise haben Sie früher bereits CODECs geschrieben, deren Lebensdauer auf die Lebensdauer des Prozesses ausgelegt war, in dem sie ausgeführt wurden. Bei WIC CODECs ist das anders. Die Windows Vista Fotogalerie, der Explorer, die Bildanzeige sowie zahlreiche andere Anwendungen basieren auf der WIC und verwenden Ihren CODEC, um Bilder und Miniaturansichten anzuzeigen. Wenn die Lebensdauer Ihres CODECs an der Lebensdauer des Prozesses ausgerichtet wäre, würde immer dann, wenn ein Bild oder eine Miniaturansicht im Windows Vista Explorer angezeigt werden, der CODEC, der für die Decodierung dieses Bildes instantiiert wurde, im Speicher verbleiben, bis der Benutzer den Computer irgendwann neu startet. Wenn Ihr CODEC nie aus dem Speicher entfernt wird, sind die von ihm genutzten Ressourcen „verloren“, weil sie nicht von einer anderen Komponente im System genutzt werden können.

Wie Sie einen CODEC WIC-fähig machen

  1. Sie implementieren eine Decoder-Klasse auf Container-Ebene und eine Decoder-Klasse auf Frame-Ebene, die die erforderlichen WIC-Schnittstellen für die Decodierung von Bildern und das Durchlaufen von Metadaten-Blöcken bereitstellen. Damit ist es allen auf WIC basierenden Anwendungen möglich, auf dieselbe Weise mit Ihrem CODEC zusammenzuarbeiten wie sie mit Standardbildformaten zusammenarbeiten.

  2. Sie implementieren eine Encoder-Klasse auf Container-Ebene und eine Encoder-Klasse auf Frame-Ebene, die die erforderlichen WIC-Schnittstellen für die Codierung von Bildern und die Serialisierung von Metadaten-Blöcken in eine Bilddatei bereitstellen.

  3. Wenn Ihr Container-Format nicht auf einem TIFF- oder JPEG-Container basiert, müssen Sie möglicherweise Metadaten-Handler für die gebräuchlichsten Metadaten-Formate (EXIF, XMP) schreiben. Wenn Sie jedoch ein auf TIFF oder JPEG basierendes Container-Format verwenden, ist dies nicht erforderlich, weil Sie an die vom System bereitgestellten Metadaten-Handler delegieren können. (Weil die meisten CODEC-Entwickler keine eigenen Metadaten-Handler implementieren müssen, wird in diesem Dokument nicht beschrieben, wie man einen Metadaten-Handler entwickelt.)

  4. Nehmen Sie in alle Ihre Bilddateien ein eindeutiges Erkennungsmuster auf (wir empfehlen eine GUID). Auf diese Weise kann Ihr Bildformat während der Erkennung Ihrem CODEC zugeordnet werden. (Wenn Sie einen WIC-Wrapper für ein vorhandenes Bildformat entwickeln, müssen Sie ein Bitmuster finden, das der Encoder immer in seine Bilddateien schreibt und das eindeutig für dieses Bildformat ist, und dieses als Erkennungsmuster benutzen.)

  5. Signieren Sie Ihren CODEC.

  6. Registrieren Sie Ihren CODEC bei der Installation. Auf diese Weise kann Ihr CODEC zur Laufzeit erkannt werden, indem die Erkennungsmuster in der Registrierung mit dem in die Bilddatei eingebetteten Muster verglichen werden.

Wichtiger Hinweis

In den Schnittstellenbeschreibungen dieses Dokuments bedeutet eine als Zwingend erforderlich gekennzeichnete Methode, dass für die Methode eine vollständige Implementierung erforderlich ist. Ist eine Methode als Optional gekennzeichnet, muss die Methode in Klassen aufgenommen werden, die die Schnittstelle implementieren, aber es ist akzeptabel, einen geeigneten Fehlercode zurückzugeben, statt eine echte Implementierung bereitzustellen.

Für bestimmte Methoden sollten Sie einen speziellen Fehlercode zurückgeben, um den Aufrufer darüber zu benachrichtigen, dass die angeforderte Funktion nicht unterstützt wird. Wenn Sie beispielsweise keine globalen Miniaturansichten unterstützen, müssen Sie in der Methode GetThumbnail den Fehlercode WINCODEC_ERR_CODECNOTHUMBNAIL zurückgeben. Wenn das Bild, das Sie codieren/decodieren, kein indiziertes Pixelformat verwendet, oder wenn Sie keine Palette auf Container-Ebene unterstützen, müssen Sie in der Methode SetPalette den Fehlercode WINCODEC_ERR_PALETTEUNAVAILABLE zurückgeben. Für alle weiteren nicht unterstützten Methoden geben Sie WINCODEC_ERR_UNSUPPORTEDOPERATION zurück.

In diesem Dokument verwende ich gelegentlich Codebeispiele, um bestimmte Vorgehensweisen zu verdeutlichen. Der Übersichtlichkeit halber habe ich alle Fehlerüberprüfungen und Verweiszähler weggelassen. Wenn Sie solche Beispiele kopieren und einfügen, beachten Sie bitte, dass der Code ohne die Fehlerüberprüfung und die Verweiszähler unvollständig ist.

Einen WIC-fähigen Decoder implementieren

Für die Implementierung eines WIC-Decoders müssen zwei Klassen geschrieben werden. Die Schnittstellen dieser Klasse entsprechen direkt den oben in Abschnitt Decodieren in Die Arbeitsweise der Windows Imaging Component beschriebenen Aufgaben des Decoders.

Eine der Klassen stellt wie oben beschrieben Dienste auf Container-Ebene bereit und implementiert die Schnittstelle IWICBitmapDecoder. Falls Ihr Bildformat Metadaten auf Container-Ebene unterstützt, müssen Sie auch die Schnittstelle IWICMetadataBlockReader für diese Klasse implementieren. Wir empfehlen, die Schnittstelle IWICBitmapCodecProgressNotification sowohl im Decoder als auch im Encoder zu unterstützen, um eine bessere Benutzererfahrung zu gewährleisten.

Die andere Klasse, die Sie implementieren, stellt Dienste auf Frame-Ebene bereit und erledigt die eigentliche Decodierung der Bild-Bits für jeden im Container enthaltenen Frame. Diese Klasse implementiert die Schnittstellen IWICBitmapFrameDecode und IWICMetadataBlockReader. Wenn Sie einen Decoder für ein Rohdaten-Format schreiben, implementieren Sie ebenfalls die Schnittstelle IWICDevelopRaw für diese Klasse. Neben den zwingend erforderlichen Schnittstellen ist es auch dringend zu empfehlen, die Schnittstelle IWICBitmapSourceTransform für diese Klasse zu implementieren, um die bestmögliche Leistung für Ihr Bildformat zu erzielen.

Eines der von der WIC bereitgestellten Objekte ist die ImagingFactory. Sie werden die Schnittstelle IWICComponentFactory dieses Objekts häufig verwenden, um verschiedene Komponenten zu erstellen. Weil Sie sie häufig verwenden werden, sollten Sie einen Verweis darauf als Elementeigenschaft in Ihren Decoder- und Encoder-Klassen anlegen.

IWICImagingFactory* m_piImagingFactory = NULL;
IWICComponentFactory* m_piComponentFactory = NULL;
HRESULT hr;

hr = CoCreateInstance(CLSID_WICImagingFactory, NULL,
     CLSCTX_INPROC_SERVER, IID_IWICImagingFactory,
     (LPVOID*) m_piImagingFactory);

hr = m_piImagingFactory->QueryInterface(
     IID_IWICComponentFactory, (void**)&m_piComponentFactory);

Decoder-Schnittstellen

Die folgenden Tabellen zeigen die von WIC-Decodern implementierten Schnittstellen. Das Klassendiagramm verdeutlicht die Vererbungshierarchie.

Decoder-Schnittstellen auf Container-Ebene

Schnittstelle

Aufgaben

Implementierung

IWICBitmapDecoder

Dienste auf Container-Ebene

Zwingend erforderlich

IWICBitmapCodecProgressNotification

Fortschrittsbenachrichtigung & Abbruch-Unterstützung

Empfohlen

IWICMetadataBlockReader

Auflistung von Metadaten

Optional (nur für Formate erforderlich, die Metadaten auf Container-Ebene unterstützen)

Decoder-Schnittstellen auf Frame-Ebene

Schnittstelle

Aufgaben

Implementierung

IWICBitmapFrameDecode

Dienste auf Frame-Ebene

Zwingend erforderlich

IWICMetadataBlockReader

Auflistung von Metadaten

Zwingend erforderlich

IWICBitmapSourceTransform

Systemeigene Decoder-Transformationen

Empfohlen

IWICDevelopRaw

Rohdaten-Verarbeitungsdienste

Nur für Rohdaten-Formate erforderlich

Abbildung 1. WIC Decoder-Schnittstellen
Abbildung 1. WIC Decoder-Schnittstellen

IWICBitmapDecoder

Wenn eine Anwendung einen Decoder anfordert, erfolgt die erste Kommunikation mit dem CODEC über die Schnittstelle IWICBitmapDecoder. Dies ist die Schnittstelle auf Container-Ebene, die Zugriff auf die Eigenschaften des Containers auf oberster Ebene bietet, und ebenso, was noch wichtiger ist, auf die darin enthaltenen Frames. Dies ist die primäre Schnittstelle in Ihrer Decoder-Klasse auf Container-Ebene.

Schnittstelle IWICBitmapDecoder : IUnknown

{
// Zwingend erforderliche Methoden
HRESULT QueryCapability ( IStream *pIStream, DWORD *pdwCapabilities );
HRESULT Initialize ( IStream *pIStream,WICDecodeOptions cacheOptions );
HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetDecoderInfo ( IWICBitmapDecoderInfo **pIDecoderInfo );
HRESULT GetFrameCount ( UINT *pCount );
HRESULT GetFrame ( UINT index, IWICBitmapFrameDecode **ppIBitmapFrame );

// Optionale Methoden
HRESULT GetPreview ( IWICBitmapSource **ppIPreview );
HRESULT GetThumbnail ( IWICBitmapSource **ppIThumbnail );
HRESULT GetColorContexts ( UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount );
HRESULT GetMetadataQueryReader ( IWICMetadataQueryReader**ppIMetadataQueryReader );
HRESULT CopyPalette ( IWICPalette *pIPalette );
}

Einige Bildformate unterstützen globale Miniaturansichten, Farbkontexte und/oder Metadaten, während viele Bildformate dies nur für einzelne Frames bereitstellen, so dass die Methoden für den Zugriff darauf in IWICBitmapDecoder optional sind, zwingend erforderlich dagegen in IWICBitmapFrameDecode. Analog dazu verwenden einige CODECs keine indizierten Pixelformate und brauchen deshalb die CopyPalette-Methoden in keiner Schnittstelle zu implementieren. Wir werden die in IWICBitmapDecoder optionalen Methoden im Abschnitt IWICBitmapFrameDecode genauer beschreiben, wo sie am häufigsten implementiert werden.

QueryCapability ist die Methode, die für die CODEC-Verteilung verwendet wird. (Weitere Informationen finden Sie unter Erkennen und Vermitteln im Abschnitt darüber, wie die Windows Imaging Component funktioniert, am Anfang dieses Dokuments.) Dies ist eine sehr wichtige Methode, denn falls zwei CODECs in der Lage sind, dasselbe Bildformat zu decodieren, oder wenn ein Musterkonflikt auftritt, weil zwei CODECs dasselbe Erkennungsmuster verwenden, ermöglicht sie uns, den CODEC auszuwählen, der für ein bestimmtes Bild am besten geeignet ist.

Wenn diese Methode aufgerufen wird, übergibt Ihnen WIC den eigentlichen Stream, der das Bild enthält. Sie sind selbst dafür verantwortlich, zu überprüfen, ob Sie alle Frames innerhalb des Bildes decodieren können, und die Metadaten-Blöcke aufzulisten, um genau festzulegen, welche Aufgaben dieser Decoder in Hinblick auf den speziellen, ihm übergebenen Datei-Stream hat. Dies ist für alle Decoder wichtig, aber insbesondere für Bildformate, die auf TIFF-Containern basieren. Der Erkennungsprozess funktioniert, indem die den Decodern in der Registrierung zugeordneten Muster mit den Mustern in der eigentlichen Bilddatei verglichen werden. Die Bereitstellung Ihres Erkennungsmusters in der Registrierung garantiert, dass Ihr Decoder immer für Bilder in Ihrem Bildformat erkannt wird, aber nicht, dass Ihr Decoder nicht für Bilder in anderen Formaten erkannt wird. Beispielsweise enthalten alle TIFF-Container das TIFF-Muster, wobei es sich um ein gültiges Erkennungsmuster für das TIFF-Bildformat handelt. Das bedeutet, dass während der Erkennung mindestens zwei Erkennungsmuster in Bilddateien für ein auf einem Container im TIFF-Stil basiertes Bildformat gefunden werden. Eines davon ist das TIFF-Muster, das andere ist das eigentliche Bildformatmuster. Es ist zwar wenig wahrscheinlich, aber es könnten auch Musterkonflikte zwischen anderen, nicht damit in Zusammenhang stehenden Bildformaten auftreten. Aus diesem Grund ist die Erkennung und Vermittlung ein zweistufiger Prozess. Überprüfen Sie immer, dass der an QueryCapabilities übergebene Bild-Stream tatsächlich eine gültige Instanz Ihres eigenen Bildformats ist. Wenn Ihr CODEC ein Bildformat decodiert, für das Sie die Spezifikation nicht besitzen, sollte Ihre Implementierung von QueryCapabilities außerdem das Vorliegen von Merkmalen überprüfen, die möglicherweise unter der Bildformatspezifikation gültig sind, die Ihr CODEC nicht implementiert. Damit stellen Sie sicher, dass die Benutzer eine gute Erfahrung mit Ihrem CODEC machen, und keine unnötigen Fehler bei der Decodierung oder unerwartete Ergebnisse erhalten.

Bevor Sie eine Operation für das Bild ausführen, müssen Sie die aktuelle Position des Streams speichern, so dass Sie ihn vor der Rückkehr von der Methode an seiner ursprünglichen Position wiederherstellen können.

Die Auflistung, die die Funktionen spezifiziert, ist wie folgt definiert:

enum WICBitmapDecoderCapabilities
{        WICBitmapDecoderCapabilitySameEncoder,
WICBitmapDecoderCapabilityCanDecodeAllImages,
WICBitmapDecoderCapabilityCanDecodeSomeImages,
WICBitmapDecoderCapabilityCanEnumerateMetadata,
WICBitmapDecoderCapabilityCanDecodeThumbnail    }

Sie sollten WICBitmapDecoderCapabilitySameEncoder nur dann deklarieren, wenn das Bild von Ihrem Encoder codiert wurde. Nachdem Sie überprüft haben, ob Sie jeden Frame im Container decodieren können, deklarieren Sie entweder WICBitmapDecoderCapabilityCanDecodeSomeImages, falls Sie einige, aber nicht alle Frames decodieren können, WICBitmapDecoderCapabilityCanDecodeAllImages, falls Sie alle Frames decodieren können, oder keines von beiden, falls Sie keinen Frame decodieren können. (Diese beiden Auflistungen schließen sich wechselseitig aus; wenn Sie WICBitmapDecoderCapabilityCanDecodeAllImages zurückgeben, wird WICBitmapDecoderCapabilityCanDecodeSomeImages ignoriert.) Deklarieren Sie WICBitmapDecoderCapabilityCanEnumerateMetadata, nachdem Sie überprüft haben, dass Sie die Metadaten-Blöcke im Bild-Container durchlaufen können. Sie müssen nicht in jedem Frame auf eine Miniaturansicht prüfen. Falls es eine globale Miniaturansicht gibt und Sie sie decodieren können, können Sie WICBitmapDecoderCapabilityCanDecodeThumbnail deklarieren. Falls es keine globale Miniaturansicht gibt, versuchen Sie, die Miniaturansicht für Frame 0 zu decodieren. Falls es nirgends eine Miniaturansicht gibt, sollten Sie diese Funktion nicht deklarieren.

Nachdem Sie die Funktionen des Decoders in Hinblick auf Ihren dieser Methode übergebenen Bild-Stream festgelegt haben, verknüpfen Sie die WICBitmapDecoderCapabilities, von denen Sie überprüft haben, dass dieser Decoder sie für dieses Bild ausführen kann, über ein logisches ODER (|) und geben das Ergebnis zurück. Denken Sie daran, den Stream an seiner ursprünglichen Position wiederherzustellen, bevor Sie zurückkehren!

Initialize wird von einer Anwendung aufgerufen, nachdem ein Decoder für die Decodierung eines bestimmten Bildes ausgewählt wurde. Der Bild-Stream wird dem Decoder übergeben. Ein Aufrufer kann optional eine Cache-Option für die Behandlung der Metadaten in der Datei spezifizieren.

enum WICDecodeOptions
{          WICDecodeMetadataCacheOnDemand,
            WICDecodeMetadataCacheOnLoad            }

Einige Anwendungen verwenden häufiger Metadaten als andere. Die meisten Anwendungen brauchen keinen Zugriff auf alle in einer Bilddatei enthaltenen Metadaten und fordern spezifische Metadaten an, wenn sie sie benötigen. Andere Anwendungen könnten stattdessen alle Metadaten vorab in den Cache stellen, statt den Datei-Stream geöffnet zu lassen, und bei jedem erforderlichen Zugriff auf Metadaten eine E/A-Operation für die Festplatte ausführen. Wenn der Aufrufer keine Cache-Option für die Metadaten vorgibt, sollte das standardmäßige Caching-Verhalten als „Cache on demand“ festgelegt werden, d.h. die Daten werden erst in den Cache gestellt, wenn das erste Mal darauf zugegriffen wird. Das bedeutet, es werden keine Metadaten in den Speicher geladen, es sei denn, die Anwendung fordert diese Metadaten gesondert an. Wenn die Anwendung WICDecodeMetadataCacheOnLoad spezifiziert, sollen die Metadaten unmittelbar in den Speicher geladen und in den Cache gestellt werden. Wenn Metadaten beim Laden in den Cache gestellt werden, kann der Datei-Stream freigegeben werden, nachdem die Metadaten in den Cache gestellt wurden.

GetContainerFormat ist eine einfach zu implementierende Methode. Sie geben einfach die GUID des Bildformats für das Bild zurück, für das der Decoder instantiiert wurde. Diese Methode ist auch in IWICMetadataBlockReader und IWICBitmapEncoder implementiert.

GetDecoderInfo gibt ein IWICBitmapDecoderInfo-Objekt zurück. Um das IWICBitmapDecoderInfo-Objekt zu erhalten, übergeben Sie einfach die GUID Ihres Decoders der Methode CreateComponentInfo in IWICComponentFactory und fordern dann die IWICDecoderInfo-Schnittstelle dafür an, wie nachfolgend gezeigt.

IWICComponentInfo* piComponentInfo = NULL;
HRESULT hr;

hr = m_piComponentFactory->CreateComponentInfo(CLSID_This,
     &piComponentInfo);
hr = piComponentInfo->QueryInterface(IID_IWICBitmapDecoderInfo,
     (void**)ppIDecoderInfo);

GetFrameCount gibt einfach die Anzahl der im Container enthaltenen Frames zurück. Einige Container-Formate unterstützen mehrere Frames, andere unterstützen nur einen Frame pro Container.

GetFrame ist die wahrscheinlich wichtigste Methode der Schnittstelle IWICBitmapDecoder, weil der Frame die eigentlichen Bild-Bits enthält, und das von dieser Methode zurückgegebene Frame-Decoder-Objekt die eigentliche Decodierung des angeforderten Bildes vornimmt. Dies ist das andere Objekt, das Sie implementieren müssen, wenn Sie einen Decoder schreiben. Weitere Informationen zu dieser Schnittstelle finden Sie unten im Abschnitt IWICBitmapFrameDecode.

GetPreview gibt eine Vorschau auf das Bild zurück. Eine genauere Beschreibung von Vorschauen finden Sie im Abschnitt zur Methode SetPreview der Schnittstelle IWICBitmapEncoder.

Falls Ihr Bildformat eine eingebettete JPEG-Vorschau enthält, brauchen Sie keinen JPEG-Decoder zu schreiben, um diese zu decodieren. Wir empfehlen Ihnen sogar dringend, dies nicht zu tun. Stattdessen sollten Sie die Aufgabe an den zusammen mit der WIC-Plattform für die Decodierung von Vorschauen und Miniaturansichten bereitgestellten JPEG-Decoder delegieren. Dazu gehen Sie im Stream zum Anfang der Vorschau-Bilddaten und rufen die Methode CreateDecoderFromStream für die Imaging Factory auf.

IWICBitmapDecoder* piPreviewDecoder = NULL;
IWICBitmapFrameDecode* piPreviewFrame = NULL;
IWICBitmapSource* piPreview = NULL;
HRESULT hr;

hr = m_piImagingFactory->CreateDecoderFromStream(m_piStream,
     NULL, WICDecodeMetadataCacheOnDemand, &piPreviewDecoder);
hr = piPreviewDecoder->GetFrame(0, piPreviewFrame);
hr = piPreviewFrame->QueryInterface(IID_IWICBitmapSource, 
     (void**)&piPreview);

IWICBitmapCodecProgressNotification

Eine der häufigsten Beschwerden von Endbenutzern über Anwendungen ist, dass sie nicht in der Lage sind, eine langandauernde Operation abzubrechen, und sie denken, die Anwendung sei abgestürzt. Häufig schließt ein Benutzer eine Anwender oder startet sogar den Computer neu, um zu versuchen, die Kontrolle über den Computer zurückzuerhalten, wenn die Anwendung nicht reagiert.

Diese Schnittstelle ermöglicht einer Anwendung, eine Callback-Funktion anzugeben, die der CODEC in vorgegebenen Zeitintervallen aufrufen kann, um den Aufrufer über den Fortschritt der aktuellen Operation zu benachrichtigen. Die Anwendung kann diese Callback-Funktion nutzen, um den Fortschritt auf der Benutzeroberfläche anzuzeigen und damit den Benutzer über den Status der Operation zu benachrichtigen. Wenn ein Benutzer im Fortschrittsdialog auf die Schaltfläche Abbrechen klickt, gibt die Anwendung von der Callback-Funktion WINCODEC_ERR_ABORTED zurück. Wenn dies passiert, muss der CODEC die angegebene Operation abbrechen und dieses HRESULT an den Aufrufer der Methode, die die Operation ausgeführt hat, weiterreichen.

Diese Schnittstelle sollte in Ihrer Decoder-Klasse auf Container-Ebene implementiert werden.

interface IWICBitmapCodecProgressNotification : public IUnknown
{
       HRESULT RegisterProgressNotification ( 
                                 PFNProgressNotification pfnProgressNotification,
                                 LPVOID pvData,
                                 DWORD dwProgressFlags );
}

RegisterProgressNotification wird von einer Anwendung aufgerufen, um eine Callback-Funktion zu registrieren, die der CODEC in vorgegebenen Zeitintervallen aufrufen kann. Der erste Parameter, pfnProgressNotification, ist ein Zeiger auf die Callback-Funktion, die der CODEC in regelmäßigen Zeitintervallen aufrufen soll.

Der Parameter pvData verweist auf ein Objekt, das der CODEC für den Aufrufer an die Callback-Funktion zurückgeben soll, wenn die Callback-Funktion aufgerufen wird. Dieses Objekt muss überhaupt nichts bewirken und hat keine besondere Bedeutung für den CODEC.

Der Parameter dwProgressFlags gibt an, wann der CODEC die Callback-Funktion aufrufen soll. Es gibt zwei Auflistungen, die für diesen Parameter logisch ODER-verknüpft (|) werden können. Es handelt sich dabei um WICProgressOperation und WICProgressNotification.

Die Auflistung WICProgressOperation gibt an, ob die Callback-Funktion während der Decodierung (WICProgressOperationCopyPixels), während der Codierung (WICProgressOperationWritePixels) oder in beiden Fällen (WICProgressOperationAll) aufgerufen werden soll.

enum WICProgressOperation
{        WICProgressOperationCopyPixels,
          WICProgressOperationWritePixels,
          WICProgressOperationAll            };

Der CODEC soll die Callback-Funktion während der Operation in regelmäßigen Zeitintervallen aufrufen, aber der Aufrufer kann bestimmte Vorgaben spezifizieren. Die Auflistung WICProgressNotification gibt an, an welcher Stelle innerhalb der Operation die Callback-Funktion aufgerufen werden soll. Wenn der Aufrufer WICProgressNotificationBegin vorgibt, müssen Sie sie zu Beginn der Operation (0.0) aufrufen. Wenn der Aufrufer dies nicht vorgibt, ist der Aufruf optional. Gibt der Aufrufer analog dazu WICProgressNotificationEnd vor, müssen Sie sie nach Abschluss der Operation (1.0) aufrufen. Wenn der Aufrufer WICProgressNotificationAll vorgibt, müssen Sie sie zu Beginn und nach Abschuss aufrufen, ebenso wie in regelmäßigen Zeitintervallen während der Operation. Der Aufrufer kann auch WICProgressNotificationFrequent vorgeben, was bedeutet, dass in häufigen Intervallen ein Callback erfolgen soll, beispielsweise nach jeweils einigen Scanzeilen. (Dieses Flag verwendet ein Aufrufer im Allgemeinen nur für ein sehr großes Bild.) In anderen Situationen ist es sinnvoll, Callbacks in Intervallen mit Inkrementschritten von etwa 10 Prozent der Gesamtzahl der zu verarbeitenden Scanzeilen durchzuführen.

enum WICProgressNotification
{        WICProgressNotificationBegin,
          WICProgressNotificationEnd,
          WICProgressNotificationFrequent,
          WICProgressNotificationAll            };

Für eine bestimmte Decoder- oder Encoder-Instanz kann jeweils nur ein Callback gleichzeitig registriert werden. Wenn eine Anwendung mehrmals RegisterProgressNotification aufruft, wird der zuvor registrierte Callback durch den neuen ersetzt. Um eine Callback-Registrierung zu beenden, setzt ein Aufrufer den Parameter pfnProgressNotification auf NULL.

PFNProgressNotification

Die Callback-Funktion hat die folgende Signatur.

typedef HRESULT (*PFNProgressNotification) ( LPVOID pvData,
ULONG uFrameNum,
WICProgressOperation operation,
double dblProgress );

Wenn Sie die Callback-Funktion aufrufen, verwenden Sie den Parameter pvData, um dieselben pvData zurückzugeben, die die Anwendung bei der Registrierung der Callback-Funktion spezifiziert hat.

Der Parameter uFrameNum sollte den Index des verarbeiteten Frames angeben.

Setzen Sie den Parameter operation auf WICProgressOperationCopyPixels, wenn Sie decodieren, und auf WICProgressOperationWritePixels, wenn Sie codieren.

Der Parameter dblProgress sollte eine Zahl zwischen 0.0 (Beginn der Operation) und 1.0 (Abschluss der Operation) enthalten. Der Wert sollte das Verhältnis aus bereits verarbeiteten Scanzeilen und der Gesamtzahl der zu verarbeitenden Scanzeilen angeben.

IWICBitmapSource

IWICBitmapSource ist eine sehr wichtige Schnittstelle für den Umgang mit Bildern aus der Perspektive einer Anwendung. Sie bildet die höchste Abstraktionsebene für eine Bildquelle, und alle WIC-Schnittstellen, die ein Bild darstellen, einschließlich IWICBitmapFrameDecode und IWICBitmap, und alle Transformationsschnittstellen (IWICBitmapScaler, IWICBitmapClipper, IWICBitmapFlipRotator und IWICFormatConverter) sind von ihr abgeleitet. Ein IWICBitmapSource-Objekt kann zu jedem beliebigen Zeitpunkt mit Hilfe einer realen Bitmap im Speicher gesichert werden. Dies erlaubt eine sehr effiziente Verarbeitung durch eine Anwendung, weil ein Bild als Abstraktion behandelt werden kann, und Transformationsoperationen in einer Transformations-Pipeline verkettet werden können, ohne dass Speicherressourcen belegt werden, bis die Anwendung bereit ist, das Bild darzustellen oder zu drucken. Zu diesem Zeitpunkt ruft sie die Methode CopyPixels für die letzte Transformation auf, um schließlich eine Bitmap des Bildes im Speicher zu erhalten, auf die die ausgewählten Transformationen angewendet wurden.

interface IWICBitmapSource : IUnknown

{

// Zwingend erforderliche Methoden

          HRESULT GetSize ( UINT *puiWidth, 
UINT *puiHeight );

          HRESULT GetPixelFormat ( WICPixelFormatGUID *pPixelFormat );

          HRESULT GetResolution ( double *pDpiX, 
double *pDpiY );

          HRESULT CopyPixels ( const WICRect *prc, 
UINT cbStride,
UINT cbBufferSize, 
BYTE *pbBuffer );

// Optionale Methode

HRESULT CopyPalette ( IWICPalette *pIPalette );

}

Aus der Perspektive eines CODECs sind die IWICBitmapSource-Methoden im Frame-Decoder-Objekt implementiert. Wir werden diese Methoden nachfolgend beschreiben, zusammen mit den anderen Methoden der Schnittstelle IWICBitmapFrameDecode, die von IWICBitmapSource abgeleitet ist.

IWICBitmapFrameDecode

IWICBitmapFrameDecode ist die Schnittstelle auf Frame-Ebene, die Zugriff auf die eigentlichen Bild-Bits bereitstellt. Sie implementieren diese Schnittstelle in Ihrer Decoder-Klasse auf Frame-Ebene. Sie ist von IWICBitmapSource abgeleitet, was bedeutet, dass Ihre Implementierung von IWICBitmapFrameDecode eine Implementierung der IWICBitmapSource-Methoden beinhaltet. Die zusätzlichen Methoden in IWICBitmapFrameDecode bieten Zugriff auf die Miniaturansicht auf Frame-Ebene, die Farbkontexte für das Bild sowie den Leser zur Metadaten-Abfrage für den Frame.

interface IWICBitmapFrameDecode : IWICBitmapSource
{
// Zwingend erforderliche Methoden
HRESULT GetThumbnail ( IWICBitmapSource **ppIThumbnail );
HRESULT GetColorContexts ( UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount );
HRESULT GetMetadataQueryReader ( IWICMetadataQueryReader**ppIMetadataQueryReader );
// Von IWICBitmapSource geerbte Methoden (erforderlich)
HRESULT GetSize ( UINT *puiWidth, UINT *puiHeight );
HRESULT GetPixelFormat ( WICPixelFormatGUID *pPixelFormat );
HRESULT GetResolution ( double *pDpiX, double *pDpiY );
HRESULT CopyPixels ( const WICRect *prc, UINT cbStride,UINT cbBufferSize, BYTE *pbBuffer );
// Optionale Methode
HRESULT CopyPalette ( IWICPalette *pIPalette );
}

GetThumbnail gibt die Miniaturansicht für den aktuellen Frame zurück. Der Leistung halber sind Miniaturansichten im Allgemeinen in einem JPEG-Format codiert. So wie für die Vorschau im Decoder ist es nicht notwendig oder empfehlenswert, einen eigenen JPEG-Decoder für Miniaturansichten bereitzustellen. Stattdessen sollten Sie an den von der WIC bereitgestellten JPEG-Decoder delegieren.

Weitere Informationen über Miniaturansichten finden Sie im Abschnitt zur Methode SetThumbnail der Schnittstelle WICBitmapFrameEncode.

GetColorContexts gibt die gültigen Farbkontexte zurück (auch als Farbprofile bezeichnet), die dem Bild in diesem Frame zugeordnet sind. Größtenteils ist dies nur ein einziger, aber es gibt Fälle, wo es zwei oder (selten) mehr sind. Der Aufrufer übergibt ein oder mehrere IWICColorContext-Objekte und setzt den Parameter cCount, um anzuzeigen, wie viele Objekte übergeben werden. Diese Methode füllt die IWICColorContext-Objekte mit den eigentlichen Farbkontextdaten für die dem Bild zugeordneten Farbprofile. Setzen Sie den Parameter pcActualCount auf die tatsächliche Anzahl an Farbkontexten, die dem Bild zugeordnet sind, auch wenn diese Anzahl höher ist als die Anzahl, die Sie zurückgeben können. (Falls mehr Farbkontexte zur Verfügung stehen, als der Aufrufer IWICColorContext-Objekte übergeben hat, erkennt der Aufrufer daran, dass weitere Farbkontexte zur Verfügung stehen.)

GetMetadataQueryReader gibt einen IWICMetadataQueryReader zurück, den eine Anwendung nutzen kann, um Metadaten für den Bild-Frame zu laden. Diese Schnittstelle wird von einem Metadaten-Handler implementiert und erlaubt einer Anwendung, bestimmte Metadaten-Eigenschaften abzufragen, die zu einem bestimmten Metadaten-Format gehören. Weitere Informationen über Metadaten-Handler finden Sie im Abschnitt über IWICMetadataBlockReader.

Um einen MetadataQueryReader zu instantiieren, rufen Sie CreateQueryReaderFromBlockReader für die ComponentFactory auf.

IWICMetadataQueryReader* piQueryReader = NULL;
HRESULT hr;

hr = m_piComponentFactory->CreateQueryReaderFromBlockReader( 
     static_cast<IWICMetadataBlockWriter*>(this),&piQueryReader);

GetSize, GetPixelFormat und GetResolution sind selbsterklärend und geben einfach die angeforderten Eigenschaften des Bildes zurück.

CopyPixels ist die interessanteste Methode in IWICBitmapSource. Eine Anwendung ruft diese Methode auf, wenn sie eine Bitmap im Speicher anlegen will, die auf dem Bildschirm oder auf dem Drucker dargestellt werden kann. Diese Methode übernimmt die eigentliche Decodierung der Bild-Bits. Die Parameter sind ein Rechteck, das den im Quellbild betrachteten Bereich darstellt, der in den Speicher kopiert werden soll, die Schrittweite die die Anzahl der Bytes in einer Scanzeile angibt, die Größe des Speicherpuffers, den die Anwendung reserviert hat, sowie ein Zeiger auf den Puffer, in den die angeforderten Bild-Bits kopiert werden sollen. (Um zu verhindern, dass mögliche Pufferüberläufe zu Sicherheitslecks führen, achten Sie darauf, nur so viele Bilddaten in den Puffer zu kopieren, wie vom Parameter cbBufferSize angegeben.)

CopyPalette muss nur von CODECs implementiert werden, die indizierte Pixelformate verwenden. Wenn ein Bild ein indiziertes Format verwendet, setzen Sie diese Methode ein, um die im Bild verwendete Farbpalette zurückzugeben. Falls Ihr CODEC kein indiziertes Format verwendet, geben Sie WINCODEC_ERR_PALETTEUNAVAILABLE zurück.

IWICMetadataBlockReader

Häufig gibt es innerhalb eines Bildes mehrere Metadaten-Blöcke, die jeweils unterschiedliche Informationstypen in unterschiedlichen Formaten bereitstellen. Im WIC-Modell sind Metadaten-Handler unterschiedliche Komponenten, die ähnlich wie Decoder zur Laufzeit erkannt werden können. Für jedes Metadaten-Format gibt es einen eigenen Handler, und jeder dieser Metadaten-Handler kann für jedes Bildformat eingesetzt werden, das die von ihm verarbeiteten Metadaten unterstützt. Wenn Ihr Bildformat also EXIF, XMP, IPTC usw. unterstützt, können Sie für diese Formate die Standard-Metadaten-Handler nutzen, die zusammen mit WIC bereitgestellt werden, und müssen keine eigenen Handler schreiben. Wenn Sie ein neues Metadaten-Format erstellen, müssen Sie natürlich einen Metadaten-Handler dafür schreiben, der genau wie die Standard-Handler zur Laufzeit erkannt und aufgerufen wird. Eine genauere Beschreibung ist im Umfang dieses Dokuments nicht möglich.

Hinweis   Wenn Ihr Bildformat auf einem TIFF- oder JPEG-Container basiert, brauchen Sie keine Metadaten-Handler zu schreiben (es sei denn, Sie entwickeln ein neues oder proprietäres Metadaten-Format). In TIFF- und JPEG-Containern befinden sich Metadaten-Blöcke in IFDs, und jeder Container hat eine andere IFD-Struktur. WIC stellt IFD-Handler für beide Container-Formate bereit, die die IFD-Struktur durchlaufen und den Zugriff auf die darin enthaltenen Metadaten an die Standard-Metadaten-Handler delegieren. Wenn Ihr Bildformat also auf einem dieser Container basiert, können Sie automatisch die IFD-Handler der WIC nutzen. Wenn Sie dagegen ein proprietäres Container-Format haben, das eine spezielle Metadaten-Struktur auf oberster Ebene besitzt, müssen Sie einen Handler schreiben, der die Struktur auf oberster Ebene durchlaufen und an die entsprechenden Metadaten-Handler delegieren kann, so wie es die IFD-Handler machen.

So wie WIC eine Abstraktionsebene für Anwendungen darstellt, die ihnen ermöglicht, über eine konsistente Schnittstellenmenge alle Bildformate auf dieselbe Weise zu verarbeiten, bietet WIC auch in Hinblick auf Metadaten-Formate eine Abstraktionsebene für CODEC-Entwickler. Wie oben bereits erwähnt, müssen die CODEC-Entwickler im Allgemeinen nicht direkt mit den verschiedenen Metadaten-Formaten arbeiten, die möglicherweise in einem Bild vorhanden sind. Jeder CODEC-Entwickler ist jedoch dafür verantwortlich, eine Möglichkeit bereitzustellen, die Metadaten-Blöcke aufzulisten, so dass für jeden Block ein geeigneter Metadaten-Handler erkannt und instantiiert werden kann. Dies ist die Aufgabe der Schnittstelle IWICMetadataBlockReader.

Sie müssen diese Schnittstelle in Ihrer Decoder-Klasse auf Frame-Ebene implementieren. Möglicherweise müssen Sie sie auch in Ihrer Decoder-Klasse auf Container-Ebene implementieren, nämlich wenn Ihr Bildformat globale Metadaten außerhalb einzelner Bild-Frames bereitstellt.

interface IWICMetadataBlockReader : IUnknown
{
// Alle Methoden zwingend erforderlich
HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetCount ( UINT *pcCount );
HRESULT GetEnumerator ( IEnumUnknown **ppIEnumMetadata );
HRESULT GetReaderByIndex ( UINT nIndex,IWICMetadataReader **ppIMetadataReader );
}

GetContainerFormat ist dasselbe wie die Methode GetContainerFormat in IWICBitmapDecoder.

GetCount gibt die Anzahl der Metadaten-Blöcke auf oberster Ebene zurück, die dem Frame zugeordnet sind.

GetEnumerator gibt einen Zähler zurück, den der Aufrufer verwenden kann, um die Metadaten-Blöcke im Frame aufzulisten und ihre Metadaten zu lesen. Um diese Methode zu implementieren, müssen Sie für jeden Metadaten-Block einen Metadaten-Leser erstellen und ein Auflistungsobjekt implementieren, das alle Metadaten-Leser auflistet. Das Auflistungsobjekt muss IEnumUnknown implementieren, so dass Sie es in IEnumUnknown umwandeln können, wenn Sie es im Parameter ppIEnumMetadata zurückgeben.

Wenn Sie das Auflistungsobjekt implementieren, können Sie alle Metadaten-Leser dann erstellen, wenn Sie zum ersten Mal das IWICMetadataBlockReader-Objekt erzeugen, oder wenn Sie zum ersten Mal das Auflistungsobjekt erzeugen, oder Sie können sie verzögert innerhalb der Implementierung der Methode IEnumUnknown::Next erzeugen. Häufig ist es effizienter, sie verzögert zu erzeugen, aber im folgenden Beispiel erzeuge ich sie alle im Konstruktor (einfach, um Platz zu sparen).

public class MetadataReaderEnumerator : public IEnumUnknown
{
   UINT m_current;
   UINT m_blockCount;
   IWICMetadataReader** m_apiMetadataReader;
   IStream* m_piStream;
   MetadataReaderEnumerator() 
{
      // Set m_blockCount to the number of metadata blocks 
      //in the frame. 
      ...
      m_apiMetadataReader = 
           WICMetadataReader*[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_piComponentFactory-> 
     CreateMetadataReaderFromContainer(
     GUID_ContainerFormatTiff, NULL, 
     WICPersistOptions.WICPersistOptionsDefault |
        WICMetadataCreationOptions.WICMetadataCreationDefault   ,
     m_piStream, &m_apiMetadataReader[x]);
   }
   }

   // Implementation of IEnumUnknown and IUnknown interfaces
   ...
}

Um die Metadaten-Leser zu erzeugen, verwenden Sie die Methode IWICComponentFactory:: CreateMetadataReaderFromContainer . Beim Aufruf dieser Methode übergeben Sie die GUID des Container-Formats im Parameter guidContainerFormat. Wenn Sie einen bevorzugten Anbieter für einen Metadaten-Leser haben, können Sie die GUID Ihres bevorzugten Anbieters im Parameter pGuidVendor übergeben. Wenn beispielsweise Ihr Unternehmen selbst Metadaten-Handler schreibt, und Sie, falls vorhanden, bevorzugt Ihre eigenen Handler verwenden, können Sie Ihre Anbieter-GUID übergeben. Größtenteils übergeben Sie jedoch NULL und überlassen es dem System, einen geeigneten Metadaten-Leser auszuwählen. Wenn Sie einen speziellen Anbieter anfordern, und dieser Anbieter einen Metadaten-Leser auf dem Computer installiert hat, gibt WIC den Leser dieses Anbieters zurück. Hat der angeforderte Anbieter jedoch keinen Metadaten-Leser auf dem Computer installiert, und es gibt einen geeigneten Metadaten-Leser, wird dieser andere Leser zurückgegeben, auch wenn er nicht vom bevorzugten Anbieter stammt. Falls sich für den im Block befindlichen Metadaten-Typ kein Metadaten-Leser auf dem Computer befindet, gibt die Komponenten-Factory den Metadaten-Handler Unknown zurück, der den Metadaten-Block als BLOB behandelt und ihn aus der Datei deserialisiert, ohne zu versuchen, ihn zu analysieren.

Für den Parameter dwOptions ODER-verknüpfen Sie die entsprechenden WICPersistOptions mit den zugehörigen WICMetadataCreationOptions. Die WICPersistOptions beschreiben die Struktur Ihres Containers. Standard ist LittleEndian.

enum WICPersistOptions
{       WICPersistOptionDefault,
WICPersistOptionLittleEndian,
WICPersistOptionBigEndian,
WICPersistOptionStrictFormat,
WICPersistOptionNoCacheStream,
WICPersistOptionPreferUTF8        };

Die WICMetadataCreationOptions geben an, ob Sie den UnknownMetadataHandler zurück erhalten wollen, wenn auf dem Computer kein Leser gefunden wird, der das Metadaten-Format aus einem bestimmten Block lesen kann. AllowUnknown ist der Standardwert, und Sie sollten immer die Erstellung des UnknownMetadataHandler zulassen. Der UnknownMetadataHandler behandelt nicht erkannte Metadaten als BLOB. Er kann sie nicht analysieren, schreibt sie aber als BLOB in den Stream und behält sie unverändert bei, wenn sie bei der Codierung zurück in den Stream geschrieben werden. Damit wird es sicher, Metadaten-Handler für proprietäre Metadaten zu erstellen, oder für Metadaten-Formate, die nicht zusammen mit dem System bereitgestellt wurden. Weil die Metadaten unverändert beibehalten werden, sind sie weiterhin vorhanden und können gelesen werden, falls später ein geeigneter Metadaten-Handler installiert wird, selbst wenn momentan kein Handler auf dem Computer vorhanden ist, der sie erkennt. Wenn Sie das Erstellen des UnknownMetadataHandler nicht zulassen, ist die Alternative, nicht erkannte Metadaten zu verwerfen oder zu überschreiben. Dies entspricht einem Datenverlust. (Beachten Sie, dass Sie, wenn Sie Ihren eigenen Metadaten-Handler für proprietäre Metadaten schreiben, niemals Verweise auf irgendetwas außerhalb des Metadaten-Blocks aufnehmen sollten. Selbst wenn der UnknownMetadataHandler die Metadaten unverändert beibehält, werden die Metadaten verschoben, wenn Dateien bearbeitet werden, und alle Verweise auf irgendetwas außerhalb des eigenen Blocks sind dann nicht mehr gültig.)

enum WICMetadataCreationOptions
{       WICMetadataCreationDefault,
         WICMetadataCreationAllowUnknown,
         WICMetadataCreationFailUnknown            }

Der Parameter pIStream ist der eigentliche Stream, den Sie decodieren. Bevor Sie den Stream übergeben, sollten Sie den Anfang des Metadaten-Blocks suchen, für den Sie einen Leser anfordern. Im Parameter ppiReader wird der geeignete Metadaten-Leser für den Metadaten-Block an der aktuellen Position im IStream zurückgegeben.

GetReaderByIndex gibt den Metadaten-Leser an dem vorgegebenen Index in der Auflistung zurück.

IWICBitmapSourceTransform

Diese Schnittstelle ist zwar optional, aber wir empfehlen Ihnen dringend, sie in Ihrer Decoder-Klasse auf Frame-Ebene zu implementieren, weil sie enorme Leistungsvorteile bringen kann. Der Gedanke hinter dieser Schnittstelle: Wenn eine Anwendung einen bestimmten betrachteten Bereich, die Größe, die Ausrichtung oder das Pixelformat angibt, statt nur das ganze Bild bei voller Auflösung zu decodieren und dann die geforderten Transformationen anzuwenden, führt WIC ein QI (Aufruf von QueryInterface) für diese Schnittstelle im IWICBitmapFrameDecode-Objekt aus. Wenn der Frame-Decoder es unterstützt, ruft WIC die geeigneten Methoden auf, um festzustellen, ob der Frame-Decoder die angeforderte Transformation durchführen kann, oder um die nächst gelegen Größe oder das Pixelformat zu ermitteln, die der Decoder für das Angeforderte bieten kann. Wenn der Decoder die angeforderten Transformationen ausführen kann, ruft WIC IWICBitmapSourceTransform::CopyPixels mit den entsprechenden Parametern auf. Wenn der Decoder einige, aber nicht alle angeforderten Transformationen ausführen kann, fordert WIC den Decoder auf, das auszuführen, was er kann, und verwendet die WIC-Transformationsobjekte (IWICBitmapScaler, IWICBitmapClipper, IWICBitmapFlipRotator und IWICFormatConverter), um die restlichen Transformationen vorzunehmen, die vom Frame-Decoder für das Ergebnis des Aufrufs von IWICBitmapSourceTransform::CopyPixels nicht ausgeführt werden konnten. Wenn der Decoder IWICBitmapSourceTransform nicht unterstützt, muss WIC die Transformationsobjekte verwenden, um alle Transformationen auszuführen. Normalerweise ist es für den Decoder sehr viel effizienter, Transformationen während der Decodierung vorzunehmen, statt zuerst das gesamte Bild zu decodieren und dann die Transformationen durchzuführen. Das gilt insbesondere für Operationen wie etwa die Skalierung auf eine sehr viel geringere Größe oder Pixelformatumwandlungen.

interface IWICBitmapSourceTransform : IUnknown
{
// Zwingend erforderliche Methoden
HRESULT DoesSupportTransform ( WICTransformOptions dstTransform,BOOL *pfIsSupported);
HRESULT CopyPixels ( WICRect *prcSrc, UINT uiWidth, UINT uiHeight,WICPixelFormatGUID * pguidDstFormat,WICBitmapTransformOptions dstTransform, UINT nStride, UINT cbBufferSize, BYTE *pbBuffer );
// Optionale Methoden
HRESULT GetClosestSize ( UINT *puiWidth,UINT *puiHeight);
HRESULT GetClosestPixelFormat ( WICPixelFormatGUID *pguidDstFormat);
}

DoesSupportTransform fragt, ob der Decoder die angeforderte Dreh- oder Kipp-Operation unterstützt. Die folgenden WICBitmapTransformOptions können angefordert werden:

enum WICBitmapTransformOptions
{       WICBitmapTransformRotate0,
WICBitmapTransformRotate90,
WICBitmapTransformRotate180,
WICBitmapTransformRotate270,
WICBitmapTransformFlipHorizontal,
WICBitmapTransformFlipVertical                }

CopyPixels ist die Methode, die die eigentliche Arbeit für die Decodierung der Bild-Bits ausführt, wie die Methode CopyPixels der Schnittstelle IWICBitmapSource, aber die Methode CopyPixels von IWICBitmapSourceTransform ist sehr viel interessanter und leistungsfähiger und kann die Bildverarbeitungsleistung wesentlich verbessern.

Wenn mehrere Transformationsoperationen angefordert werden, ist das Ergebnis von der Reihenfolge abhängig, in der die Operationen ausgeführt werden. Um Vorhersehbarkeit und Konsistenz zwischen den CODECs sicherzustellen, ist es wichtig, dass alle CODECs diese Operationen in derselben Reihenfolge ausführen. Nachfolgend die kanonische Reihenfolge für die Ausführung dieser Operationen.

  1. Skalieren

  2. Zuschneiden

  3. Drehen

Pixelformatumwandlungen können jederzeit ausgeführt werden, weil sie keine Wirkung auf die anderen Transformationen haben.

Der erste Parameter, prcSrc, gibt den betreffenden Bereich für das Zuschneiden des Bildes an. Konventionsgemäß erfolgt das Skalieren vor dem Zuschneiden. Wenn das Bild also sowohl skaliert als auch zugeschnitten werden soll, sollte der betreffende Bereich ermittelt werden, nachdem das Bild skaliert wurde.

Der zweite und der dritte Parameter geben die Größe an, auf die das Bild skaliert werden soll.

Der Parameter pguidDstFormat gibt das angeforderte Pixelformat für das decodierte Bild an. Weil WIC GetClosestPixelFormat bereits aufgerufen hat, sollte es sich hierbei um ein Pixelformat handeln, für das der Decoder bereits seine Unterstützung angezeigt hat.

Der Parameter dstTransform gibt den angeforderten Drehwinkel an und/oder ob das Bild vertikal und/oder horizontal gekippt werden soll. Auch hier hat WIC bereits

DoesSupportTransform aufgerufen, so dass der Decoder für die angeforderte Transformation bereits Unterstützung angezeigt hat. Beachten Sie, dass die Drehung immer nach der Skalierung und nach dem Zuschneiden erfolgen sollte.

GetClosestSize nimmt zwei Eingabe/Ausgabe-Parameter entgegen. Der Aufrufer verwendet die Parameter puiWidth und puiHeight, um die Größe anzugeben, in der er das Bild im Idealfall decodieren lassen möchte. Ein Decoder kann ein Bild jedoch nur bis zu einer Größe decodieren, die ein Vielfaches seiner DCT-Größe darstellt, und unterschiedliche Bildformate können unterschiedliche DCT-Größen haben. Der Decoder sollte also abhängig von seiner eigenen DCT-Größe feststellen, wie nah er an die angeforderte Größe herankommt, und dann puiWidth und puiHeight auf diese Größen setzen. Wenn eine größere Größe angefordert wurde, der CODEC aber keine Vergrößerung unterstützt, sollte das Original zurückgegeben werden.

GetClosestPixelFormat wird verwendet, um das am besten geeignete Pixelformat für das angeforderte Pixelformat zu ermitteln, das der Decoder ohne Datenverlust bereitstellen kann. Unbedingt zu beachten ist hier, dass es immer besser ist, ein breiteres Pixelformat in ein schmaleres umzuwandeln, auch wenn dadurch die Bildgröße wächst, weil es gegebenenfalls immer in ein restriktiveres Format umgewandelt werden kann, Daten aber, nachdem sie verloren sind, nicht wiederhergestellt werden können.

IWICDevelopRaw

Diese Schnittstelle bietet Verarbeitungsmethoden, die spezifisch für die Rohdaten-Bildverarbeitung sind. Alle Rohdaten-CODECs müssen die Schnittstelle IWICDevelopRaw unterstützen. Einige Rohdaten-CODECs sind möglicherweise nicht in der Lage, jede von dieser Schnittstelle vorgegebene Einstellung zu unterstützen, aber Sie sollten alle Einstellungen unterstützen, die Ihr CODEC ausführen kann. Zumindest sollte jeder Rohdaten-CODEC die Methoden SetRotation und SetRenderQuality implementieren.

Darüber hinaus sind einige Methoden und Schnittstellen, die für andere CODECs optional sind, für Rohdaten-CODECs dringend empfohlen. Dabei handelt es sich unter anderem um die Methoden GetPreview und GetThumbnail in der Decoder-Klasse auf Container-Ebene sowie um die Schnittstelle IWICBitmapSourceTransform in der Decoder-Klasse auf Frame-Ebene.

Einstellungen, die unter Verwendung der IWICDevelopRaw-Methoden festgelegt wurden, sollten von dem CODEC konsistent zu der Vorgehensweise für andere Metadaten beibehalten werden, aber Sie sollten niemals die ursprünglichen „Aufnahme“-Einstellungen überschreiben. Durch Beibehaltung der Metadaten und Implementierung von LoadParameterSet und GetCurrentParameterSet erlauben Sie Rohdaten-Verarbeitungsanwendungen, die Einstellungen für die Verarbeitung sitzungsübergreifend zu laden und anzuwenden.

Eine sehr wichtige Aufgabe der Schnittstelle IWICDevelopRaw ist es, Anwendungsentwicklern zu ermöglichen, eine Benutzeroberfläche für die Anpassung der Rohdaten-Parameter zu erstellen, die so konsistent wie möglich über verschiedene CODECs hinweg funktioniert. Angenommen, ein Endbenutzer passt diese Parameter unter Verwendung eines Schiebereglers an, dessen Minimum- und Maximumwerte auf die Minimum-und Maximumbereiche für den Parameter abgebildet sind. Um dies zu unterstützen, sollten Sie unbedingt alle Parameterbereiche als linear behandeln. Um sicherzustellen, dass die Schieberegler nicht zu sensibel sind, sollten Sie auch für jeden Parameter einen möglichst großen Bereich unterstützen, der mindestens 50 Prozent des maximal möglichen Bereichs abdeckt. Erstreckt sich beispielsweise der maximal mögliche Bereich für den Kontrast von reinem Grau bis zu reinem Schwarzweiß, und der Standardwert ist auf 0.0 abgebildet, geht der von einem CODEC mindestens zu unterstützende Bereich von mindestens der Hälfte zwischen dem Standardwert und reinem Grau am unteren Ende (-1.0) bis mindestens zur Hälfte zwischen dem Standardwert und reinem Schwarzweiß am oberen Ende (+1.0).

interface IWICDevelopRaw : IWICBitmapFrameDecode
{
HRESULT QueryRawCapabilitiesInfo ( WICRawCapabilitiesInfo *pInfo );
HRESULT LoadParameterSet ( WICRawParameterSet parameterSet );
HRESULT GetCurrentParameterSet ( IPropertyBag2 **ppCurrentParameterSet );
HRESULT SetExposureCompensation ( double ev );
HRESULT GetExposureCompensation ( double *pEV );
HRESULT SetWhitePointRGB ( UINT Red, UINT Green, UINT Blue );
HRESULT GetWhitePointRGB ( UINT *pRed, UINT *pGreen, UINT *pBlue );
HRESULT SetNamedWhitePoint ( WICNamedWhitePoint whitePoint );
HRESULT GetNamedWhitePoint ( WICNamedWhitePoint *pWhitePoint );
HRESULT SetWhitePointKelvin ( UINT whitePointKelvin );
HRESULT GetWhitePointKelvin ( UINT *pWhitePointKelvin );
HRESULT GetKelvinRangeInfo ( UINT *pMinKelvinTemp,UINT *pMaxKelvinTemp,UINT *pKelvinTempStepValue );
HRESULT SetContrast ( double contrast );
HRESULT GetContrast (double *pContrast );
HRESULT SetGamma ( double gamma );
HRESULT GetGamma (double *pGamma );
HRESULT SetSharpness ( double sharpness );
HRESULT GetSharpness ( double *pSharpness );
HRESULT SetSaturation ( double saturation );
HRESULT GetSaturation ( double *pSaturation );
HRESULT SetTint ( double tint );
HRESULT GetTint ( double *pTint );
HRESULT SetNoiseReduction ( double noiseReduction );
HRESULT GetNoiseReduction ( double *pNoiseReduction );
HRESULT SetDestinationColorContext (const IWICColorContext *pColorContext );
HRESULT SetToneCurve ( UINT cbToneCurveSize,const WICRawToneCurve *pToneCurve );
HRESULT GetToneCurve ( UINT cbToneCurveBufferSize,WICRawToneCurve *pToneCurve,UINT *pcbActualToneCurveBufferSize );
HRESULT SetRotation ( double rotation );
HRESULT GetRotation ( double *pRotation );
HRESULT SetRenderQuality ( WICRawRenderQuality renderQuality );
HRESULT GetRenderQuality ( WICRawRenderQuality *pRenderQuality );
HRESULT SetNotificationCallback ( IWICDevelopRawNotificationCallback *pCallback );}

QueryRawCapabilitiesInfo gibt die Menge der unterstützten Funktionen für diese Rohdatendatei zurück. Die Struktur IWICRawCapabilitiesInfo ist wie folgt definiert.

struct WICRawCapabilitiesInfo
{
         UINT cbSize;
         UINT CodecMajorVersion;
         UINT CodecMinorVersion;
         WICRawCapabilities ExposureCompensationSupport;
         WICRawCapabilities ContrastSupport;
         WICRawCapabilities RGBWhitePointSupport;
         WICRawCapabilities NamedWhitePointSupport;
         UINT NamedWhitePointSupportMask;
         WICRawCapabilities KelvinWhitePointSupport;
         WICRawCapabilities GammaSupport;
         WICRawCapabilities TintSupport;
         WICRawCapabilities SaturationSupport;
         WICRawCapabilities SharpnessSupport;
         WICRawCapabilities NoiseReductionSupport;
         WICRawCapabilities DestinationColorProfileSupport;
         WICRawCapabilities ToneCurveSupport;
         WICRawRotationCapabilities RotationSupport;
}

Die in dieser Struktur verwendete Auflistung WICRawCapabilities ist wie folgt definiert:

         enum WICRawCapabilities 
{       WICRawCapabilityNotSupported,
WICRawCapabilityGetSupported,
WICRawCapabilityFullySupported        }

Das letzte Feld ist eine WICRawRotationCapabilities-Auflistung, die wie folgt definiert ist:

        enum WICRawRotationCapabilities
{       WICRawRotationCapabilityNotSupported,
WICRawRotationCapabilityGetSupported,
WICRawRotationCapabilityNinetyDegreesSupported
WICRawRotationCapabilityFullySupported            }

LoadParameterSet ermöglicht dem Benutzer, anzugeben, ob die bei der Aufnahme verwendeten Einstellungen genutzt werden sollen, oder ob der Decoder aufgefordert werden soll, das Bild automatisch zu korrigieren.

         enum WICRawParameterSet
{       WICAsShotParameterSet,
WICUserAdjustedParameterSet,
WICAutoAdjustedParameterSet        }

GetCurrentParameterSet gibt eine IPropertyBag2 mit der aktuellen Parametermenge zurück. Der Aufrufer kann diese Parametermenge dem Encoder übergeben, der sie als Optionen für die Codierung benutzen kann.

Set/GetExposureCompensation gibt die Belichtungskompensierung an, die auf das Endergebnis anzuwenden ist. Der gültige Bereich für EV ist -5.0 bis +5.0 Stops.

Set/GetWhitePointRGB, Set/GetNamedWhitePoint, Set/GetWhitePointKelvin und GetKelvinRangeInfo bieten Möglichkeiten, den Weißpunkt zu ermitteln und zu setzen, und zwar entweder als RGB-Wert, als vorab festgelegter benannter Wert oder als Kelvin-Wert. Der mögliche Bereich für Kelvin beträgt 1.500 - 30.000.

SetContrast/GetContrast gibt an, welcher Kontrastbetrag auf die Ausgabe angewendet werden soll. Der gültige Bereich für die Angabe des Kontrasts ist -1.0 bis +1.0. Der Standardkontrast ist 0.0.

Set/GetGamma gibt das anzuwendende Gamma an. Der gültige Bereich für Gamma ist 0.2 bis 5.0. 1.0 ist der Standardwert. Gamma wird im Allgemeinen unter Verwendung der herkömmlichen Gamma-Potenzfunktion (einer linearen Potenzfunktion mit dem Verstärkungsfaktor 1) implementiert. Mit wachsendem Gamma nimmt die Helligkeit zu, und sie nimmt ab, wenn Gamma gegen Null geht. (Beachten Sie, dass der Minimumwert nicht Null ist, weil Null dazu führen würde, dass in den herkömmlichen Gamma-Berechnungen eine Division durch Null auftreten würde. Die logische Mindestgrenze beträgt 1/max, deshalb ist das Minimum gleich 0.2.)

Set/GetSharpness gibt den Betrag der anzuwendenden Schärfe an. Der gültige Bereich ist -1.0 bis +1.0. 0.0 ist der Standardbetrag für die Schärfe, und -1.0 gibt an, dass überhaupt keine Schärfe angewendet werden soll.

Set/GetSaturation gibt den Betrag der anzuwendenden Sättigung an. Der gültige Bereich für die Angabe der Sättigung ist -1.0 bis +1.0, wobei 0.0 die normale Sättigung ist. -1.0 stellt die komplette Entsättigung dar, und +1.0 stellt die Vollsättigung dar.

Set/GetTint zeigt den anzuwendenden Farbton an, beschränkt auf Grün/Magenta. Der gültige Bereich ist -1.0 bis +1.0, wobei Grün auf der negativen Seite der Skala liegt, und Magenta auf der positiven Seite. Die Farbtonskala ist als orthogonal zur Farbtemperatur definiert.

Set/GetNoiseReduction zeigt den Betrag der anzuwendenden Rauschreduzierung an. Der gültige Bereich ist -1.0 bis +1.0. 0.0 gibt den Standardbetrag für die Rauschreduzierung an, -1.0 bedeutet keine Rauschreduzierung, +1.0 steht für eine maximale Rauschreduzierung.

SetDestinationColorContext gibt das auf das Bild anzuwendende Farbprofil an. Sie können IWICBitmapFrameDecode::GetColorContext aufrufen, um das aktuelle Farbprofil zu laden.

Set/GetToneCurve gibt die anzuwendende Farbtiefenkurve an. Vorausgesetzt wird eine lineare Interpolation zwischen Punkten. Die pToneCurve ist eine WICRawToneCurve-Struktur, die ein Feld mit WICRawToneCurvePoint-Strukturen enthält, ebenso wie einen Zähler für die Anzahl der Punkte im Feld.

struct WICRawToneCurve 
{
          UINT cPoints;
          WICRawToneCurvePoint aPoints[];
}

Ein WICRawToneCurvePoint enthält einen Eingabewert und einen Ausgabewert.

struct WICRawToneCurvePoint 
{
          double Input;
          double Output;
}

Wenn der Aufrufer im Parameter pToneCurve den Wert NULL übergibt, sollten Sie die angeforderte Größe für die WICRawToneCurve im Parameter pcbActualToneCurveBufferSize zurückgeben.

Set/GetRotation gibt den anzuwendenden Drehungsgrad an. Eine Drehung von 90.0 steht für eine Drehung von 90 Grad im Uhrzeigersinn. (Der Unterschied zwischen der Verwendung von IWICDevelopRaw::SetRotation und der Festlegung der Drehung über die Methode IWICBitmapSourceTransform::CopyPixels besteht darin, dass der Drehwinkel, der mit IWICDevelopRaw::SetRotation gesetzt wird, vom CODEC beibehalten wird, während bei der Einstellung der Drehung über IWICBitmapSourceTransform::CopyPixels das Bild nur im Speicher gedreht wird.

Set/GetRenderQuality gibt die vom Aufrufer angeforderte Ausgabequalität an. Wenn ein Benutzer Parameter anpasst, sollte die Anwendung in der Lage sein, eine sehr schnelle Annäherung dessen anzuzeigen, wie das eigentliche Bild nach Anwendung der Änderungen aussieht. Für diesen Zweck wird das Bild normalerweise mit Bildschirmauflösung oder weniger angezeigt, und nicht mit der tatsächlichen Bildauflösung. Das Wichtigste dabei ist, dem Benutzer ein unmittelbares Feedback zu bieten. Dies ist der Fall, wenn eine Anwendung die Qualität im Entwurfsmodus (Draft Mode) anfordert, deshalb sollte dies sehr schnell sein. Nachdem der Benutzer alle Änderungen vorgenommen hat, sie im Entwurfsmodus als Vorschau angesehen hat und dann entscheidet, das vollständige Bild unter Verwendung der aktuellen Einstellungen zu decodieren, fordert die Anwendung die Decodierung in der besten Qualität (Best Quality) an. Dies wird normalerweise auch für den Druck gefordert. Wo eine sinnvolle Abwägung zwischen Schnelligkeit und Qualität erforderlich ist, fordert die Anwendung Normalqualität (Normal Quality) an.

enum WICRawRenderQuality
{       WICRawRenderQualityDraftMode,
WICRawRenderQualityNormalQuality,
WICRawRenderQualityBestQuality        }

SetNotificationCallback registriert eine Callback-Funktion, die der Decoder aufrufen kann, wenn sich einer der Rohdaten-Verarbeitungsparameter ändert. Die Signatur für den IWICDevelopRawNotificationCallback hat nur eine Methode, Notify. Notify verwendet einen einzigen Parameter, wobei es sich um eine Maske handelt, die angibt, welche der Rohdaten-Verarbeitungsparameter sich geändert haben.

HRESULT Notify ( UINT NotificationMask );

Die folgenden Werte können für die NotificationMask ODER-verknüpft werden.

WICRawChangeNotification_ExposureCompensation
WICRawChangeNotification_NamedWhitePoint
WICRawChangeNotification_KelvinWhitePoint
WICRawChangeNotification_RGBWhitePoint
WICRawChangeNotification_Contrast
WICRawChangeNotification_Gamma
WICRawChangeNotification_Sharpness
WICRawChangeNotification_Saturation
WICRawChangeNotification_Tint
WICRawChangeNotification_NoiseReduction
WICRawChangeNotification_DestinationColorContext
WICRawChangeNotification_ToneCurve
WICRawChangeNotification_Rotation
WICRawChangeNotification_RenderMode

Einen WIC-fähigen Encoder implementieren

So wie für die Implementierung eines WIC-Decoders ist es auch für die Implementierung eines WIC-Encoders erforderlich, zwei Klassen zu schreiben. Die Schnittstellen dieser Klassen entsprechen direkt den Aufgaben des Encoders, die im Abschnitt Codieren des Kapitels „Die Arbeitsweise der Windows Imaging Component“ beschrieben sind.

Eine der Klassen stellt Dienste auf Container-Ebene bereit und verwaltet die Serialisierung der einzelnen Bild-Frames innerhalb des Containers. Diese Klasse implementiert die Schnittstelle IWICBitmapEncoder. Wenn Ihr Bildformat Metadaten auf Container-Ebene unterstützt, müssen Sie auch die Schnittstelle IWICMetadataBlockWriter für diese Klasse implementieren.

Die andere Klasse stellt Dienste auf Frame-Ebene bereit und übernimmt die eigentliche Codierung der Bild-Bits für jeden im Container enthaltenen Frame. Außerdem durchläuft sie die Metadaten-Blöcke für jeden Frame und fordert die entsprechenden Metadaten-Schreiber für die Serialisierung der Blöcke an. Diese Klasse implementiert die Schnittstelle IWICBitmapFrameEncode und die Schnittstelle IWICMetadataBlockWriter. Diese Klasse sollte ein IStream-Element haben, das die Klasse auf Container-Ebene bei der Instantiierung initialisiert, und in das die Methode Commit die Frame-Daten serialisiert.

In einigen Fällen, wie beispielsweise bei Rohdatenformaten, will der Entwickler nicht unbedingt, dass die Anwendungen in der Lage sein sollen, das Rohdatenformat zu codieren oder erneut in das Rohdatenformat zu codieren, weil die Aufgabe einer Rohdatendatei ist, die Sensordaten genau so zu aufzunehmen, wie sie von der Kamera kommen. In Fällen, wo der CODEC-Entwickler keine Codierung zulassen will, ist es dennoch erforderlich, einen grundlegenden Encoder zu implementieren, um einfach das Hinzufügen von Metadaten zu ermöglichen. In diesem Fall muss der Encoder nur Methoden unterstützen, die für das Schreiben von Metadaten erforderlich sind, und kann die Bild-Bits unverändert vom Decoder kopieren.

Encoder-Schnittstellen

Die folgende Tabelle zeigt die von WIC-Encodern implementierten Schnittstellen. Das Klassendiagramm verdeutlicht die Vererbungshierarchie.

Encoder-Schnittstellen auf Container-Ebene

Schnittstelle

Aufgaben

Implementierung

IWICBitmapEncoder

Dienste auf Container-Ebene

Zwingend erforderlich

IWICBitmapCodecProgressNotification

Fortschrittsbenachrichtigungen und Abbruch-Unterstützung

Empfohlen

IWICMetadataBlockWriter

Metadaten-Serialisierungsdienste

Optional (nur für Formate erforderlich, die Metadaten auf Container-Ebene unterstützen)

Encoder-Schnittstellen auf Frame-Ebene

Schnittstelle

Aufgaben

Implementierung

IWICBitmapFrameEncode

Dienste auf Frame-Ebene

Zwingend erforderlich

IWICMetadataBlockWriter

Metadaten-Serialisierungsdienste

Zwingend erforderlich

Abbildung 2. WIC Encoder-Schnittstellen
Abbildung 2. WIC Encoder-Schnittstellen

Sie erkennen, dass sich die Encoder-Schnittstellen fast spiegelbildlich zu den Decoder-Schnittstellen verhalten, und dass die meisten der Methoden dieser Schnittstellen den Methoden der zugehörigen Decoder-Schnittstellen entsprechen. Nachdem Sie bereits wissen, wie die Implementierung eines WIC-fähigen Decoders erfolgt, wird Ihnen auch die Implementierung eines WIC-fähigen Encoders vertraut vorkommen.

IWICBitmapEncoder

Diese Schnittstelle ist das Gegenstück zur Schnittstelle IWICBitmapDecoder und stellt den Ausgangspunkt für die Codierung einer Bilddatei dar. So wie IWICBitmapDecoder für das Laden von Eigenschaften auf Container-Ebene und einzelner Frames aus dem Bild-Container verwendet wird, wird IWICBitmapEncoder verwendet, um Eigenschaften auf Container-Ebene zu setzen und einzelne Bild-Frames in den Container zu serialisieren. Sie implementieren diese Schnittstelle in Ihrer Encoder-Klasse auf Container-Ebene.

interface IWICBitmapEncoder : public IUnknown
{
// Zwingend erforderliche Methoden
HRESULT Initialize ( IStream *pIStream,WICBitmapEncoderCacheOption cacheOption );HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetEncoderInfo ( IWICBitmapEncoderInfo **pIEncoderInfo );
HRESULT CreateNewFrame ( IWICBitmapFrameEncode **ppIFrameEncode,IPropertyBag2 **ppIEncoderOptions );
HRESULT Commit ( void );
// Optionale Methoden
HRESULT SetPreview ( IWICBitmapSource *pIPreview );
HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
HRESULT SetColorContexts ( UINT cCount,IWICColorContext **ppIColorContext );
HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter **ppIMetadataQueryWriter );
HRESULT SetPalette ( IWICPalette *pIPalette);
};

Aus der Beschreibung der Decoder wissen Sie, dass einige Bildformate globale Miniaturansichten, Farbkontexte und/oder Metadaten unterstützen, während viele Bildformate dies nur für einzelne Frames bereitstellen. Aus diesem Grund sind die Methoden für ihre Einstellung für IWICBitmapEncoder optional, zwingend erforderlich dagegen für IWICBitmapFrameEncode. Wir werden die optionalen Methoden für IWICBitmapEncoder im Abschnitt über IWICBitmapFrameEncode genauer beschreiben, wo sie am häufigsten implementiert werden.

Falls Sie keine globalen Miniaturansichten unterstützen, geben Sie WINCODEC_ERR_CODECNOTHUMBNAIL von der Methode SetThumbnail in IWICBitmapEncoder zurück. Wenn Sie keine Palette auf Container-Ebene unterstützen, oder wenn das Bild, das Sie codieren, kein indiziertes Format besitzt, geben Sie WINCODEC_ERR_PALETTEUNAVAILABLE von der Methode SetPalette zurück. Für alle anderen nicht unterstützten Methoden geben Sie WINCODEC_ERR_UNSUPPORTEDOPERATION zurück.

Initialize ist die erste Methode, die für einen IWICBitmapEncoder aufgerufen wird, nachdem dieser instantiiert wurde. Dem Encoder wird ein Bild-Stream übergeben, und ein Aufrufer kann optional eine Cache-Option vorgeben. Im Fall des Decoders ist der Stream schreibgeschützt, aber der einem Encoder übergebene Stream ist ein Stream, in den geschrieben werden kann, und in den der Encoder alle Bilddaten und Metadaten serialisiert. Die Cache-Optionen für den Encoder unterscheiden sich ebenfalls.

enum WICBitmapEncoderCacheOption
{       WICBitmapEncoderCacheInMemory,
WICBitmapEncoderCacheTempFile,
WICBitmapEncoderNoCache        }

Die Anwendung hat die Wahl, den Encoder aufzufordern, die Bilddaten in den Speicher als Cache zu schreiben, sie in eine temporäre Datei als Cache zu schreiben, oder sie direkt in die Datei auf der Festplatte zu schreiben, ohne einen Cache zu verwenden. Wenn der Encoder aufgefordert wird, die Daten in eine temporären Datei als Cache zu schreiben, sollte der Encoder eine temporäre Datei auf der Festplatte anlegen und direkt in diese Datei schreiben, ohne ein Caching im Speicher durchzuführen. Wenn der Aufrufer keine Cache-Option auswählt, muss jeder Frame übernommen werden, bevor der nächste Frame erzeugt werden kann.

GetContainerFormat wird genau wie die Methode GetContainerFormat für IWICBitmapDecoder implementiert.

GetEncoderInfo gibt ein IWICBitmapEncoderInfo-Objekt zurück. Um das IWICBitmapEncoderInfo-Objekt zu erhalten, übergeben Sie einfach die GUID Ihres Encoders an die Methode CreateComponentInfo von IWICComponentFactory und fordern dann die Schnittstelle IWICEncoderInfo dafür an.

Betrachten Sie das Beispiel unter IWICBitmapDecoder::GetDecoderInfo.

CreateNewFrame ist das Encoder-Gegenstück zu GetFrame von IWICBitmapDecoder. Diese Methode gibt ein IWICBitmapFrameEncode-Objekt zurück. Dies ist das Objekt, das letztlich die Bilddaten für einen bestimmten Frame innerhalb des Containers serialisiert.

Einer der Vorteile von WIC ist, dass sie eine Abstraktionsschicht für Anwendungen bereitstellt, die ihnen ermöglicht, mit allen Bildformaten auf dieselbe Weise umzugehen, aber natürlich sind nicht alle Bildformate genau gleich. Einige Bildformate haben Funktionen, die von anderen nicht unterstützt werden, und damit Anwendungen diese speziellen Funktionen nutzen können, ist es notwendig, für den CODEC eine Möglichkeit zu schaffen, sie darzustellen. Das ist der Zweck der Encoder-Optionen. Wenn Ihr CODEC irgendwelche Encoder-Optionen unterstützt, sollten Sie ein IPropertyBag2-Objekt anlegen, das die von Ihnen unterstützten Encoder-Optionen anzeigt, und es im Parameter ppIEncoderOptions dieser Methode zurückgeben. Der Aufrufer kann dieses IPropertyBag2-Objekt verwenden, um festzustellen, welche Encoder-Optionen Ihr CODEC unterstützt. Wenn der Aufrufer Werte für eine der unterstützten Encoder-Funktionen angeben will, weist er den Wert der zugehörigen Eigenschaft im IPropertyBag2-Objekt zu und übergibt sie dem neu erzeugten IWICBitmapFrameEncode-Objekt in seiner Methode Initialize.

Um ein IPropertyBag2-Objekt zu instantiieren, müssen Sie zuerst eine PROPBAG2-Struktur erzeugen, um jede von Ihrem Encoder unterstützte Encoder-Funktion anzugeben, ebenso wie den Datentyp für jede Eigenschaft. Anschließend müssen Sie ein IPopertyBag2-Objekt implementieren, das Wertebereiche für jede zu schreibende Eigenschaft erzwingt, und alle konfliktverursachenden oder überlappenden Werte korrigiert. Für einfache Mengen nicht konfliktverursachender Optionen können Sie die Methode IWICComponentFactory::CreateEncoderPropertyBag aufrufen, die ein einfaches IPropertyBag2-Objekt für Sie erzeugt und dazu die in Ihrer PROPBAG2-Struktur angegebenen Eigenschaften verwendet. Sie müssen jedoch noch die Wertebereiche erzwingen. Für komplexere Encoder-Optionen, oder wenn Sie konfliktverursachende Werte korrigieren müssen, sollten Sie Ihre eigene IPropertyBag2-Implementierung schreiben.

UINT cuiPropertyCount = 0;
IPropertyBag2* piPropertyBag = NULL;
PROPBAG2* pPropBagOptions;
HRESULT hr;

// Insert code here to initialize piPoropertyBag with the 
// supported options for your encoder, and to initialize 
// cuiPropertyCount to the number of encoder option properties
// you're exposing.
...

hr = piComponentFactory->CreateEncoderPropertyBag( 
                   pPropBagOptions, cuiPropertyCount, &piPropertyBag );

WIC stellt eine kleine Menge kanonischer Encoder-Optionen bereit, die von einigen der gebräuchlichsten Bildformate verwendet werden. Alle kanonischen Encoder-Optionen sind optional, und ein CODEC muss keine davon unterstützen. Der Grund dafür, warum sie als kanonische Optionen bereitgestellt werden, ist, dass viele Anwendungen eine Benutzeroberfläche für Benutzer anbieten, wo sie diese Optionen angeben können, wenn sie eine Bilddatei in einem von ihnen unterstützten Format speichern. Die Bereitstellung einer kanonischen Methode, mit der diese Optionen angegeben werden, macht es für Anwendungen einfach, sie den Encodern auf konsistente Weise mitzuteilen. Die kanonischen Encoder-Optionen sind in der nachfolgenden Tabelle aufgelistet.

Encoder-Option

VARTYPE

Wertebereich

Lossless (Verlustfrei)

VT_BOOL

True/False

ImageQuality (Bildqualität)

VT_R4

0-1.0

CompressionQuality (Komprimierungsqualität)

VT_R4

0-1.0

BitmapTransform (Bitmap-Transformation)

VT_UI1

WICBitmapTransformOptions

Wenn Ihr CODEC eine verlustfreie Codierung unterstützt, sollten Sie die Encoder-Option Lossless bereitstellen, damit Anwendungen anfordern können, dass ein Bild verlustfrei codiert werden soll. Wenn ein Aufrufer diese Eigenschaft auf True setzt, sollten Sie die Option ImageQuality ignorieren und das Bild verlustfrei codieren.

Die Option ImageQuality erlaubt einer Anwendung, den Treuegrad anzugeben, mit dem das Bild codiert werden soll. Diese Option erlaubt dem Benutzer eine Abwägung zwischen Bildqualität und Geschwindigkeit und/oder Dateigröße. JPEG ist ein Beispiel für ein Bildformat, das diese Abwägung unterstützt. Ein Wert von 0.0 zeigt an, dass die Bildtreue weniger wichtig ist, und der Encoder den Algorithmus mit dem größten Verlust verwenden soll. Der Wert 1.0 gibt an, dass die Bildtreue über alles geht und der Encoder die höchstmögliche Bildtreue beibehalten soll. (Abhängig von Ihrem CODEC kann dies synonym zur Option Lossless sein. Wenn Ihr CODEC jedoch eine verlustfreie Codierung unterstützt, und die Option Lossless auf True gesetzt ist, sollte die Option ImageQuality ignoriert werden.)

Die Option CompressionQuality erlaubt einer Anwendung, die bei der Codierung des Bildes verwendete Komprimierungseffizienz vorzugeben. Ein sehr effizienter Algorithmus erzeugt unter Umständen eine kleinere Bilddatei mit derselben Qualität wie ein weniger effizienter Komprimierungsalgorithmus, braucht aber möglicherweise länger für die Codierung. Diese Option ermöglicht einem Benutzer, eine Abwägung zwischen der Dateigröße und der Codierungsgeschwindigkeit zu treffen, während dieselbe Qualität beibehalten wird. TIFF ist ein Beispiel für ein Bildformat, das diese Abwägung unterstützt. (Beachten Sie, dass ein Format wie JPEG unterschiedliche Kompressionsstufen unterstützt, aber eine höhere Kompressionsstufe zu einer geringeren Bildqualität führt. Aus diesem Grund würde ein JPEG CODEC die Option ImageQuality statt der Option CompressionQuality bereitstellen.) Ein Wert von 0.0 für diese Option zeigt an, dass das Bild so schnell wie möglich komprimiert werden soll, ohne die Bildtreue zu reduzieren, auch wenn das auf Kosten einer größeren Dateigröße geschieht. Ein Wert von 1.0 zeigt an, dass Sie die kleinstmögliche Dateigröße erzeugen sollen (mit derselben Qualität), unabhängig davon, wie lange die Codierung dauert. Ein CODEC kann sowohl die Option ImageQuality als auch die Option CompressionQuality unterstützen, wobei die Option ImageQuality das akzeptable Verlustmaß angibt, und die Option CompressionQuality eine Abwägung zwischen Größe und Geschwindigkeit für die vorgegebene Qualität erlaubt.

Die Option BitmapTransform stellt eine Möglichkeit für den Aufrufer bereit, während der Codierung einen Drehwinkel oder eine horizontale Kippausrichtung vorzugeben. Die Auflistung WICBitmapTransformOptions, mit der die angeforderte Transformation spezifiziert wird, ist dieselbe Auflistung, die für die Anforderung einer Transformation während der Decodierung über die Schnittstelle IWICBitmapSourceTransform bereitgestellt wird.

Beachten Sie, dass Encoder nicht auf die kanonischen Encoder-Optionen beschränkt sind. Die Aufgabe von Encoder-Optionen ist es, den Encodern zu ermöglichen, ihre Funktionen bereitzustellen, und es gibt keine Beschränkung in Hinblick auf die Funktionstypen, die dabei angeboten werden können. Sie sollten darauf achten, dass Ihre Encoder-Optionen ausreichend dokumentiert sind, denn auch wenn eine Option die von dieser Methode zurückgegebene Eigenschaftsmenge nutzen kann, um die Namen, Typen und Wertebereiche für die von Ihnen unterstützten Optionen zu ermitteln, ist Ihre Dokumentation die einzige Möglichkeit, ihre Bedeutung zu erfahren oder herauszufinden, wie sie auf der Benutzeroberfläche bereitgestellt werden können.

Commit ist die Methode, die Sie aufrufen, nachdem alle Bilddaten und Metadaten in den Stream serialisiert wurden. Sie sollten diese Methode verwenden, um die Vorschau-Bilddaten in den Stream zu serialisieren, ebenso wie gegebenenfalls globale Miniaturansichten, Metadaten, Paletten usw. Diese Methode sollte den Datei-Stream nicht schließen, weil erwartet wird, dass die Anwendung den Stream schließt, die ihn geöffnet hat.

Der Abschnitt über die Methode IWICBitmapFrameEncode:Commit beschreibt detailliert, wie IWICBitmapEncoderCacheOptions das Verhalten dieser Methode beeinflusst.

SetPreview wird verwendet, um eine Vorschau für das Bild zu erstellen. Es ist zwar nicht zwingend erforderlich, dass jedes Bild eine Vorschau hat, aber es ist dringen zu empfehlen. Moderne Digitalkameras und Scanner erzeugen Bilder mit einer sehr hohen Auflösung, die im Allgemeinen sehr groß sind und demzufolge für die Decodierung sehr viel Verarbeitungszeit benötigen. Die Bilder der nächsten Kamerageneration werden noch größer. Um eine möglichst gute Wahrnehmung für den Benutzer zu bieten, ist es sehr empfehlenswert, eine kleinere Version eines Bildes mit niedrigerer Auflösung bereitzustellen, normalerweise im JPEG-Format, das schnell decodiert und „sofort“ angezeigt werden kann, wenn ein Benutzer es anfordert. Eine Anwendung kann dazu eine Vorschau anfordern, bevor sie die Decodierung des eigentlichen Bildes anfordert, so dass eine bessere Wahrnehmung für den Benutzer entsteht, und er zumindest eine Darstellung des Bildes in Bildschirmgröße erhält, während er darauf wartet, dass das eigentliche Bild decodiert wird. Während es für alle CODECs sinnvoll ist, Vorschauen bereitzustellen, ist es für CODECs, die IWICBitmapSourceTransform nicht unterstützen, eine absolute Notwendigkeit.

Wenn Sie eine JPEG-Vorschau bereitstellen, brauchen Sie keinen JPEG-Encoder für ihre Codierung zu schreiben. Sie sollten die Codierung von Vorschauen und Miniaturansichten an den JPEG-Encoder delegieren, den Sie zusammen mit der WIC-Plattform erhalten haben.

IWICBitmapCodecProgressNotification

Die Schnittstelle IWICBitmapCodecProgressNotification ist optional, aber ihre Implementierung in der Encoder-Klasse auf Container-Ebene ist empfehlenswert. Diese Schnittstelle ist im Abschnitt Decoder dieses Dokuments genauer beschrieben. Die Implementierung ist für Decoder und Encoder gleich.

IWICBitmapFrameEncode

Diese Schnittstelle ist das Encoder-Gegenstück zur Schnittstelle IWICBitmapFrameDecode. Sie implementieren diese Schnittstelle in Ihrer Encoder-Klasse auf Frame-Ebene, nämlich in der Klasse, die die eigentliche Codierung der Bild-Bits für jeden Frame durchführt.

interface IWICBitmapFrameEncode : public IUnknown
{
// Zwingend erforderliche Methoden
HRESULT Initialize ( IPropertyBag2 *pIEncoderOptions );
HRESULT SetSize ( UINT width,UINT height );
HRESULT SetResolution ( double dpiX,double dpiY );
HRESULT SetPixelFormat (WICPixelFormatGUID *pPixelFormat);
HRESULT SetColorContexts ( UINT cCount,IWICColorContext **ppIColorContext );
HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter **ppIMetadataQueryWriter );
HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
HRESULT WritePixels ( UINT lineCount,UINT cbStride,UINT cbBufferSize,BYTE *pbPixels );
HRESULT WriteSource ( IWICBitmapSource *pIWICBitmapSource,WICRect *prc );
HRESULT Commit ( void );
// Optionale Methode
HRESULT SetPalette ( IWICPalette *pIPalette );};

Initialize ist die erste Methode, die für ein IWICBitmapFrameEncode-Objekt nach seiner Instantiierung aufgerufen wird. Diese Methode verwendet einen einzigen Parameter, der optional ist. Dieser Parameter stellt die Encoder-Optionen dar und ist dieselbe IPropertyBag2-Instanz, die Sie in der Methode CreateNewFrame des Decoders auf Container-Ebene erzeugt und im Parameter pIEncoderOptions dieser Methode an den Aufrufer zurückgegeben haben. Zu diesem Zeitpunkt haben Sie die Struktur IPropertyBag2 mit Eigenschaften gefüllt, die die von Ihrem Encoder auf Frame-Ebene unterstützten Encoder-Optionen darstellen. Der Aufrufer hat jetzt Werte für diese Eigenschaften bereitgestellt, um die Parameter für die gewünschte Codierungsoption anzugeben, und gibt dasselbe Objekt zurück an Sie, um das IWICBitmapFrameEncode-Objekt zu initialisieren. Sie sollten bei der Codierung der Bild-Bits die angegebenen Optionen anwenden.

SetSize und SetResolution sind selbsterklärend. Der Aufrufer verwendet diese Methoden, um die Größe und die Auflösung für das codierte Bild vorzugeben.

SetPixelFormat wird verwendet, um ein Pixelformat für die Codierung des Bildes anzufordern. Wenn das angeforderte Pixelformat nicht unterstützt wird, sollten Sie in pPixelFormat, einem Eingabe/Ausgabe-Parameter, die GUID des am besten geeigneten Pixelformats zurückgeben, das unterstützt wird.

SetColorContexts wird verwendet, um einen oder mehrere gültige Farbkontexte (auch als Farbprofile bezeichnet) für dieses Bild anzugeben. Es ist wichtig, die Farbkontexte anzugeben, so dass eine Anwendung, die ein Bild später decodiert, von dem Quellfarbprofil in das Zielprofil auf dem für die Anzeige oder den Ausdruck verwendeten Gerät umwandeln kann. Ohne ein Farbprofil ist es unmöglich, auf unterschiedlichen Geräten konsistente Farben zu erzielen, was für Endbenutzer ein enormes Frustpotential darstellt, nämlich wenn ihre Fotos auf unterschiedlichen Bildschirmen unterschiedlich aussehen, und wenn sie keinen Ausdruck anfertigen können, der mit dem übereinstimmt, was sie auf dem Bildschirm sehen.

GetMetadataQueryWriter gibt einen IWICMetadataQueryWriter zurück, den eine Anwendung nutzen kann, um bestimmte Metadaten-Eigenschaften in einem Metadaten-Block im Bild-Frame einzufügen oder zu bearbeiten.

Es gibt mehrere Möglichkeiten, einen IWICMetadataQueryWriter aus der IWICComponentFactory zu instantiieren. Sie können ihn entweder aus Ihrem IWICMetadataBlockWriter erzeugen, und zwar genauso, wie Sie einen IWICMetadataQueryReader aus einem IWICMetadataBlockReader in der Methode GetMetadataQueryReader der Schnittstelle IWICBitmapFrameDecode erzeugt haben.

IWICMetadataQueryWriter* piMetadataQueryWriter = NULL;
HRESULT hr;

hr = m_piComponentFactory->CreateQueryWriterFromBlockWriter( 
       static_cast<IWICMetadataBlockWriter*>(this), 
       &piMetadataQueryWriter);

Sie können ihn auch aus einem vorhandenen IWICMetadataQueryReader erstellen, wie etwa demjenigen, den wir durch Anwendung der oben angesprochenen Methode erhalten haben.

hr = m_piComponentFactory->CreateQueryWriterFromReader( 
       piMetadataQueryReader, pguidVendor, &piMetadataQueryWriter);

Der Parameter pguidVendor erlaubt Ihnen, einen bestimmten Anbieter für den für die Instantiierung eines Metadaten-Schreibers zu verwendenden QueryWriters anzugeben. Wenn Sie beispielsweise Ihre eigenen Metadaten-Schreiber bereitstellen, können Sie Ihre eigene Anbieter-GUID angeben. Dieser Parameter ist optional, und Sie können NULL übergeben, wenn Sie keine Vorgaben machen möchten.

SetThumbnail wird verwendet, um eine Miniaturansicht bereitzustellen. Alle Bilder sollten eine Miniaturansicht bereitstellen, entweder global, für jeden Frame oder beides. Die Methoden GetThumbnail und SetThumbnail sind auf Container-Ebene optional, aber wenn ein CODEC WINCODEC_ERR_CODECNOTHUMBNAIL von der Methode GetThumbnail in IWICBitmapDecoder zurückgibt, ruft WIC die Methode GetThumbnail in IWICBitmapFrameDecode für Frame 0 auf. Wenn nirgendwo eine Miniaturansicht gefunden wird, muss WIC das vollständige Bild decodieren und es auf die Größe einer Miniaturansicht bringen, was für große Bilder eine wesentliche Leistungseinbuße darstellen kann.

Die Miniaturansicht sollte eine Größe und eine Auflösung besitzen, die ein schnelles Decodieren und eine unmittelbare Anzeige erlauben. Aus diesem Grund sind Miniaturansichten größtenteils JPEG-Bilder. Beachten Sie, dass Sie, wenn Sie JPEG für Ihre Miniaturansichten verwenden, keinen JPEC-Encoder und auch keinen JPEC-Encoder für die Codierung oder Decodierung schreiben müssen. Sie sollten das Codieren und Decodieren von Miniaturansichten immer an den JPEG CODEC delegieren, den Sie zusammen mit der WIC-Plattform erhalten haben.

WritePixels ist die Methode, mit der Scanzeilen aus einer Bitmap für die Codierung in den Speicher weitergegeben werden. Die Methode wird wiederholt aufgerufen, bis alle Scanzeilen übergeben wurden. Der Parameter lineCount gibt an, wie viele Scanzeilen in diesem Aufruf geschrieben werden sollen. Der Parameter cbStride gibt die Anzahl der Bytes pro Scanzeile an. cbBufferSize gibt die Größe des im Parameter pbPixels übergebenen Puffers an, der die eigentlichen Bild-Bits enthält, die codiert werden sollen. Wenn die kombinierte Höhe der Scanzeilen aus kumulativen Aufrufen größer ist als die in der Methode SetSize angegebene Höhe, geben Sie WINCODEC_ERR_TOOMANYSCANLINES zurück.

Wenn die WICBitmapEncoderCacheOption gleich WICBitmapEncoderCacheInMemory ist, sollen die Scanzeilen im Speicher in den Cache gestellt werden, bis alle Scanzeilen übergeben wurden. Wenn die Cache-Option des Encoders gleich WICBitmapEncoderCacheTempFile ist, sollen die Scanzeilen in einer temporären Datei in den Cache gestellt werden, die bei der Initialisierung des Objekts erzeugt wird. In beiden Situationen sollte das Bild erst dann codiert werden, wenn der Aufrufer Commit aufruft. Wenn die Cache-Option gleich WICBitmapEncoderNoCache ist, soll der Encoder die Scanzeilen sofort beim Empfang codieren, falls das möglich ist. (In einigen Formaten ist es nicht möglich, und die Scanzeilen müssen in den Cache gestellt werden, bis Commit aufgerufen wird.)

Es ist wahrscheinlich, dass die meisten Rohdaten-CODECs WritePixels nicht implementieren, weil sie keine Veränderung der Bild-Bits in der Rohdatendatei unterstützen. Rohdaten-CODECs sollten jedoch weiterhin WriteSource implementieren, denn wenn Metadaten hinzugefügt werden, kann dadurch die Dateigröße wachsen, so dass die Datei neu auf die Festplatte geschrieben werden muss. In diesem Fall muss man in der Lage sein, die vorhandenen Bild-Bits zu kopieren, und genau das erledigt die Methode WriteSource.

WriteSource wird verwendet, um ein IWICBitmapSource-Objekt zu codieren. Der erste Parameter ist ein Zeiger auf ein IWICBitmapSource-Objekt. Der zweite Parameter ist ein WICRect, das den für die Codierung vorgesehenen Bereich angibt. Diese Methode kann mehrmals nacheinander aufgerufen werden, solange die Breite jedes Rechtecks dieselbe Breite hat wie das endgültig zu codierende Bild. Wenn sich die im Parameter prc übergebene Breite des Rechtecks von der in der Methode SetSize angegebenen Breite unterscheidet, geben Sie WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS zurück. Wenn die kombinierte Höhe der Scanzeilen aus den kumulativen Aufrufen größer als die in der Methode SetSize angegebenen Höhe ist, geben Sie WINCODEC_ERR_TOOMANYSCANLINES zurück.

Die Cache-Optionen verhalten sich bei dieser Methode genau wie bei der zuvor beschriebenen Methode WritePixels.

Commit ist die Methode, die die codierten Bild-Bits in den Datei-Stream serialisiert, und alle Metadaten-Schreiber für den Frame durchläuft und sie auffordert, ihre Metadaten in den Stream zu serialisieren. Falls die Cache-Option des Encoders gleich WICBitmapEncoderCacheInMemory oder WICBitmapEncoderCacheTempFile ist, ist diese Methode auch für die Codierung des Bildes verantwortlich, und wenn die Cache-Option gleich WICBitmapEncoderCacheTempFile ist, sollte die Methode Commit auch die temporäre Datei löschen, die als Cache für die Bilddaten verwendet wurde, bevor die Codierung durchgeführt wird.

Diese Methode wird immer aufgerufen, nachdem alle Scanzeilen oder Rechtecke, aus denen sich das Bild zusammensetzt, mit den Methoden WritePixels oder WriteSourceübergeben wurden. Die Größe des fertigen Rechtecks, die sich aus den kumulierten Aufrufen von WritePixels oder WriteSource zusammensetzt, muss gleich der in der Methode SetSize angegebenen Größe sein. Stimmt die Größe nicht mit der erwarteten Größe überein, sollte diese Methode WINCODECERROR_UNEXPECTEDSIZE zurückgeben.

Um die Metadaten-Schreiber zu durchlaufen und jeden Metadaten-Schreiber anzuweisen, seine Metadaten in den Stream zu serialisieren, rufen Sie GetWriterByIndex auf, um die Schreiber für jeden Block zu durchlaufen, und rufen IWICPersistStream.Save für jeden Metadaten-Schreiber auf.

IWICMetadataWriter* piMetadataWRiter = NULL;
IWICPersistStream* piPersistStream = NULL;
HRESULT hr;
for (UINT x=0; x < m_blockCount; x++) 
{
    hr = GetWriterByIndex(x, & piMetadataWriter);
    hr = piMetadataWriter->QueryInterface( 
         IID_IWICPersistStream,(void**)&piPersistStream);
    
    hr = piPersistStream->Save(m_piStream, 
       WICPersistOptions.WicPersistOptionDefault, true);
    ...
}

SetPalette muss nur von CODECs implementiert werden, die indizierte Formate verwenden. Wenn ein Bild ein indiziertes Format einsetzt, benutzen Sie diese Methode, um die im Bild verwendete Farbpalette anzugeben. Wenn Ihr CODEC kein indiziertes Format verwendet, geben Sie WINCODEC_ERR_PALETTEUNAVAILABLE von dieser Methode zurück.

IWICMetadataBlockWriter

Die Encoder-Klasse auf Frame-Ebene implementiert diese Schnittstelle, um alle Metadaten-Blöcke bereitzustellen, und fordert den geeigneten Metadaten-Schreiber für jeden Block an. Wenn Ihr Bildformat globale Metadaten außerhalb einzelner Frames unterstützt, sollten Sie diese Schnittstelle auch für die Encoder-Klasse auf Container-Ebene implementieren. Weitere Informationen über Metadaten-Handler finden Sie im Abschnitt über den IWICMetadataBlockReader im Abschnitt zur Implementierung eines WIC-fähigen Decoders.

interface IWICMetadataBlockWriter : IWICMetadataBlockReader
{
// Alle Methoden zwingend erforderlich
HRESULT InitializeFromBlockReader ( IWICMetadataBlockReader *pIMDBlockReader );
HRESULT GetWriterByIndex ( UINT nIndex, IWICMetadataWriter **ppIMetadataWriter );
HRESULT AddWriter (IWICMetadataWriter *pIMetadataWriter );
HRESULT SetWriterByIndex ( UINT nIndex,IWICMetadataWriter *pIMetadataWriter );
HRESULT RemoveWriterByIndex ( UINT nIndex );
}

InitializeFromBlockReader verwendet einen IWICMetadataBlockReader, um den Block-Schreiber zu initialisieren. Sie erhalten den IWICMetadataBlockReader von dem Decoder, der das Bild decodiert hat.

UINT blockCount = 0;
IWICMetadataReader* piMetadataReader = NULL;
IWICMetadataWriter** apiMetadataWriter = NULL;
HRESULT hr;

hr = m_piBlockReader->GetCount(&blockCount);
apiMetadataWriter = IWICMetadataWriter*[blockCount];
for (UINT x=0; x < blockCount; x++)
{
   hr = m_piBlockReader-   >GetReaderByIndex(&piMetadataReader);
   hr = m_piComponentFactory->CreateMetadataWriterFromReader(
        piMetadataReader, NULL, &apiMetadataWriter[x]);
}

Die Initialisierung des IWICMetadataBlockWriter mit einem IWICMetadataBlockReader instantiiert einen Metadaten-Schreiber für jeden von dem IWICMetadataBlockReader-Objekt bereitgestellten Metadaten-Leser, so dass die Anwendung nicht für jeden Metadaten-Block explizit einen Schreiber anfordern muss.

GetWriterByIndex gibt das IWICMetadataWriter-Objekt für den n-ten Metadaten-Block zurück, wobei n der im Parameter nIndex übergebene Wert ist. Falls kein Metadaten-Schreiber registriert ist, der den Metadaten-Typ in dem n-ten Block verarbeiten kann, gibt die Komponenten-Factory den Metadaten-Handler Unknown zurück, der den Metadaten-Block als BLOB behandelt. Er serialisiert ihn als Bit-Stream, ohne zu versuchen, ihn zu analysieren.

AddWriter erlaubt einem Aufrufer, einen neuen Metadaten-Schreiber hinzuzufügen. Das ist erforderlich, wenn eine Anwendung Metadaten eines anderen Formats hinzufügen will, als sie in den vorhandenen Metadaten-Blöcken enthalten sind. Beispielsweise könnte es für eine Anwendung erforderlich sein, XMP-Metadaten hinzuzufügen. Wenn es keinen vorhandenen XMP-Metadaten-Block gibt, muss die Anwendung einen XMP-Metadaten-Schreiber instantiieren und ihn mit Hilfe der Methode AddWriter in die Menge der Metadaten-Schreiber aufnehmen.

SetWriterByIndex wird verwendet, um einen Metadaten-Schreiber an einem bestimmten Index innerhalb der Menge einzufügen. Wenn es an diesem Index bereits einen Metadaten-Schreiber gibt, wird er durch den neuen ersetzt.

RemoveWriterByIndex wird verwendet, um einen Metadaten-Schreiber aus der Menge zu entfernen.

Installation und Registrierung von CODECs

Wenn Sie einen CODEC installieren, müssen Sie ihn in der Registrierung registrieren und sicherstellen, dass der Miniaturansicht-Cache aktualisiert wird, falls es bereits Bilder in Ihrem Format auf dem Computer gibt.

In diesem Abschnitt beschreiben wir alle Registrierungsschlüssel, die Sie erstellen müssen, um Ihren CODEC zu registrieren und dafür zu sorgen, dass er bei der Erkennung berücksichtigt wird. Außerdem beschreiben wir die Einträge, die ihm ermöglichen, an der Metadaten-Suche sowie an den Aktualisierungsfunktionen der Vista Fotogalerie und des Windows Explorers teilzunehmen. Darüber hinaus beschreiben wir das API, das Sie in Ihrem CODEC-Installationsprogramm aufrufen müssen, um den Miniaturansicht-Cache für alle Bilder zu aktualisieren, die sich in Ihrem Format bereits auf dem Computer befinden. Schließlich zeigen wir, wie Sie es den Benutzern leichter machen können, Ihren CODEC zu finden und zu installieren, wenn sie bereits Bilder Ihres Bildformats auf ihrem Computer haben.

Ihren CODEC signieren

Wie bereits im Abschnitt über Erkennen und Vermitteln beschrieben, müssen alle CODECs signiert werden, um am WIC-Erkennungsprozess teilnehmen zu können. WIC lädt keinen CODEC, der nicht von einer vertrauenswürdigen Zertifizierungsorganisation (z. B. Verisign) signiert ist. Weitere Informationen über die Signatur finden Sie in der Dokumentation des Windows Vista SDK.

Ihren CODEC registrieren

Wenn Sie einen CODEC registrieren, registrieren Sie eigentlich zwei Komponenten - den Encoder und den Decoder. Außerdem müssen Sie Registrierungseinträge anlegen, um Ihr Container-Format bei den Metadaten-Handlern für die von Ihrem Bildformat unterstützten Metadaten-Formate zu registrieren.

Registrierungseinträge für Encoder und Decoder

Die folgenden Registrierungseinträge müssen separat sowohl für den Decoder als auch für den Encoder erstellt werden.

HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},Author = "Name des Autors"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},Description = "Beschreibung von Encoder oder Decoder"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},DeviceManufacturer = "Kamerahersteller "
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},DeviceModels = "Gerät, Gerät"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},FriendlyName = "Name des Encoders oder Decoders"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},FileExtensions = ".foo, .abc, .xyz"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},Date = "mm-dd-yyyy"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},VendorGUID = {Vendor GUID}
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},ContainerFormat = {ContainerFormat GUID}
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},Version = "Major.Minor.Build.Number"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},SpecVersion = "Major.Minor.Build.Number"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},MimeTypes = "image/foo,image/foo"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},SupportAnimation = 0 or 1
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},SupportChromakey = 0 or 1
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},SupportLossless = 0 or 1
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},SupportMultiframe = 0 or 1
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},Formats\{PixelFormat GUID}
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},InProcServer32\(Default) = "drive:\path\yourdll.dll"
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},InProcServer32\ThreadingModel = "Apartment" | "Both" 

Die Einträge FriendlyName, VendorGUID, ContainerFormat, MimeTypes, FileExtensions und Formats sind zwingend erforderlich. Alle anderen Einträge sind optional.

Während die meisten dieser Einträge selbsterklärend sind, sind für einige davon ein paar Anmerkungen erforderlich. Die Einträge DeviceManufacturer und DeviceModels sind spezifisch für Rohdaten-CODECs und beziehen sich auf den Kamerahersteller und die Kameramodelle, auf die der CODEC angewendet werden kann. Die spec-Version ist die Version des Bildformats spec, mit dem der CODEC übereinstimmt. Der Eintrag Formats gibt die von dem CODEC unterstützten Pixelformate an. Ein CODEC kann mehrere Pixelformate unterstützen. Wenn dies bei Ihnen der Fall ist, müssen Sie mehrere Schlüssel unter HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID}\Formats eintragen.

Encoder-spezifische Registrierungseinträge

Neben den oben für den Encoder aufgelisteten Einträgen ist es auch erforderlich, dass Sie Ihren Encoder unter der Kategorie der WIC-Encoder auflisten, so dass das Erkennungsmodul ihn findet. Dazu nehmen Sie die folgenden Registrierungseinträge vor. Die erste GUID in den folgenden Einträgen ist die CATID für WICBitmapEncoders.

HKEY_CLASSES_ROOT\CLSID\{AC757296-3522-4E11-9862-C17BE5A1767E}\Instance\{Encoder CLSID},CLSID = {Encoder CLSID}
HKEY_CLASSES_ROOT\CLSID\{AC757296-3522-4E11-9862-C17BE5A1767E}\Instance\{Encoder CLSID},Friendly Name = "Name of Encoder"
Ein neues Container-Format bei Metadaten-Schreibern registrieren

Wenn Sie ein neues Container-Format für Ihren CODEC erstellen, müssen Sie auch Registrierungseinträge anlegen, um Metadaten-Schreiber für die Metadaten-Blöcke in Ihren Bildern zu unterstützen. Die folgenden Einträge müssen unter der CLSID des Metadaten-Schreibers für jedes in Ihrem Container-Format unterstützte Metadaten-Format erstellt werden. Wenn Ihr CODEC einen TIFF-Container verwendet, befindet sich diese Information bereits in der Registrierung und Sie brauchen diese Einträge nicht zu erstellen.

HKEY_CLASSES_ROOT\CLSID\{Metadata Writer CLSID}\Containers\{Container-Format GUID},WritePosition = Offset zu seinem Container
HKEY_CLASSES_ROOT\CLSID\{Metadata Writer CLSID}\Containers\{Container-Format GUID},WriteHeader = Muster für den Metadaten-Header
HKEY_CLASSES_ROOT\CLSID\{Metadata Writer CLSID}\Containers\{Container-Format GUID},WriteOffset = Offset vom Anfang des Headers

Wenn Sie ein Container-Format im TIFF- oder JPEG-Stil verwenden, müssen Sie eine Zuordnung zwischen Ihrem Container und diesem Container-Format registrieren. Eine genauere Beschreibung finden Sie im nachfolgenden Abschnitt über Integration in den Windows-Eigenschaftenspeicher.

Decoder-spezifische Registrierungseinträge

Neben den für alle Encoder und Decoder erforderlichen Registrierungseinträgen sind die folgenden Registrierungseinträge speziell für Decoder erforderlich.

Diese Einträge registrieren Ihren Decoder unter der Kategorie WIC Decoders. Die erste GUID in diesen Einträgen ist die CATID für WICBitmapDecoders.

HKEY_CLASSES_ROOT\CLSID\{7ED96837-96F0-4812-B211-F13C24117ED3}\Instance\{Decoder CLSID},CLSID = {Decoder CLSID}
HKEY_CLASSES_ROOT\CLSID\{7ED96837-96F0-4812-B211-F13C24117ED3}\Instance\{Decoder CLSID},Friendly Name = "Name des Decoders"

Wie bereits im Abschnitt Erkennen und Verteilen beschrieben, basiert der Mechanismus, der die Zuteilung eines geeigneten Decoders für ein bestimmtes Bild ermöglicht, auf dem Vergleich eines in die Bilddatei eingebetteten Erkennungsmusters mit einem im Registrierungseintrag für den Decoder angegebenen Muster. Um die Laufzeiterkennung für Decoder zu aktivieren, müssen Sie das eindeutige Muster für Ihr Bildformat wie folgt registrieren. Alle diese Registrierungseinträge sind zwingend erforderlich, außer dem Eintrag EndOfStream, der optional ist, wie nachfolgend beschrieben.

HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns\0,Position = Offset im Block
HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns\0,Length = Länge des Musters
HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns\0,Pattern = Vergleichsmuster
HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns\0,Mask = FF FF FF FF
HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns\0,EndOfStream= 0 oder 1

Der Wert Position gibt den Offset innerhalb der Datei an, wo das Muster zu finden ist.

Der Wert Length gibt die Länge des Musters an.

Der Wert Pattern gibt die eigentlichen Bits an, aus denen das Muster besteht. Dies sind die Bits, die während der Erkennung mit dem Erkennungsmuster in einer Bilddatei verglichen werden.

Der Wert Mask erlaubt die Verwendung von Wildcard-Werten in Mustern. Die Maske wird angewendet, indem eine logische UND-Verknüpfung für Muster und Maske durchgeführt wird. Jedes Bit im Muster, das einem Bit mit dem Wert 0 in der Maske entspricht, wird ignoriert.

Der Wert EndOfStream gibt, falls vorhanden, an, ob der Offset des Erkennungsmusters vom Ende statt vom Anfang des Streams aus berechnet werden soll. Einige Bildformate legen die Erkennungsmuster am Ende der Datei oder in geringer Entfernung zum Ende ab. Der Standard ist, vom Beginn an zu suchen, wenn sich also Ihr Muster nicht in der Nähe des Dateiendes befindet, können Sie diesen Eintrag weglassen.

Ein CODEC kann mehrere Erkennungsmuster unterstützen. In diesem Fall wiederholen Sie alle Schlüssel unter HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns und verwenden einen numerischen Schlüssel (in diesem Beispiel 0), um zwischen den verschiedenen Mustern zu unterscheiden. Sie müssen unter dem Schlüssel für jedes Muster alle vier Werte angeben.

Ein neues Container-Format bei Metadaten-Lesern registrieren

Wenn Sie ein neues Container-Format für Ihren CODEC erstellen, müssen Sie auch Registrierungseinträge erstellen, um die Erkennung von Metadaten-Lesern für die in Ihren Bildern verwendeten Metadaten-Blöcke zu unterstützen, so wie Sie es auch für die Metadaten-Schreiber gemacht haben. Die folgenden Einträge müssen unter der CLSID des Metadaten-Lesers für jedes von Ihrem Container-Format unterstützten Metadaten-Leser erstellt werden. (Beachten Sie, dass sich diese Information bereits in der Registrierung befindet, wenn Ihr CODEC einen TIFF-Container verwendet.)

HKEY_CLASSES_ROOT\CLSID\{Metadata Reader CLSID}\Containers\{Container-Format GUID}\0,Position = Offset relativ zu seinem Container
HKEY_CLASSES_ROOT\CLSID\{Metadata Reader CLSID}\Containers\{Container-Format GUID}\0,Pattern = Muster für den Metadaten-Header
HKEY_CLASSES_ROOT\CLSID\{Metadata Reader CLSID}\Containers\{Container Format GUID}\0,Mask = FF FF FF FF
HKEY_CLASSES_ROOT\CLSID\{Metadata Reader CLSID}\Containers\{Container-Format GUID}\0,DataOffset = Offset vom Anfang des Headers

Weil die Einträge für Metadaten-Leser auch für die Erkennung verwendet werden, sind sie den Einträgen für Decoder sehr ähnlich. Diese Einträge werden von der Komponenten-Factory verwendet, um die von Ihrem Container unterstützten Metadaten-Leser zu finden, und um den am besten geeigneten Leser zu finden, wenn Ihre IWICMetadataBlockReader-Implementierung einen Metadaten-Leser anfordert.

Der Wert Position gibt den Offset im Container des Metadaten-Blocks an, wo der Metadaten-Header zu finden ist. Für Metadaten-Blöcke auf oberster Ebene ist dies der Offset im Datei-Stream. Für Metadaten-Blöcke, die in andere Metadaten-Blöcke verschachtelt sind, ist es der Offset, der sich auf den umschließenden Metadaten-Block bezieht.

Das Pattern für den Metadaten-Header wird im Allgemeinen von dem Metadaten-Handler definiert, und Sie sollten für jeden Leser den standardmäßigen Metadaten-Header verwenden, es sei denn, es gibt einen guten Grund dafür, dass das Muster in Ihrem Container ein anderes Format erhalten muss.

Der DataOffset ist optional und gibt den Offset vom Beginn des Metadaten-Headers an, wo die eigentlichen Daten anfangen. Wenn sich die Metadaten nicht an einem bestimmten Offset in Bezug auf den Header befinden, kann dieser Eintrag weggelassen werden.

Integration in Windows Vista Fotogalerie und Windows Explorer

Um zu ermöglichen, dass die Vista Fotogalerie und der Windows Explorer Miniaturansichten anzeigen und Standard-Bildmetadaten suchen und aktualisieren, muss ein CODEC eine Implementierung der Schnittstelle IThumbnailProvider und der ihr zugeordneten Schnittstelle IPropertyStore besitzen. Die Schnittstelle IThumbnailProvider wird verwendet, um Miniaturansichten zu finden und den Miniaturansicht-Cache zu füllen, und die Schnittstelle IPropertyStore wird für die Suche und die Aktualisierung von einer Datei zugeordneten Metadaten verwendet. Alle Dateitypen in Windows Vista haben Miniaturansichten und Metadaten, aber für unterschiedliche Dateitypen sind unterschiedliche Implementierungen dieser Schnittstellen erforderlich, um die Miniaturansichten und Metadaten für sie zu laden oder zu erzeugen. Windows Vista stellt Standardimplementierungen für diese Schnittstellen bereit. Die Standardimplementierung von IThumbnailProvider kann für jedes WIC-fähige Bildformat verwendet werden. Die Standardimplementierung von IPropertyStore kann für jedes WIC-fähige Bildformat verwendet werden, das auf einem TIFF- oder auf einem JPEG-Container basiert. Um Ihr Bildformat den Standardimplementierungen dieser beiden Schnittstellen zuzuordnen, brauchen Sie nur ein paar Registrierungseinträge hinzuzufügen.

Die folgenden Einträge zeigen der Vista Fotogalerie und dem Windows Explorer an, dass einem Bildformat eine Dateinamenerweiterung (.ext) und der zugehörige Mimetyp zugeordnet sind.

HKEY_CLASSES_ROOT\.ext,ContentType = "Mimetype des Bildformats"HKEY_CLASSES_ROOT\.ext,PerceivedType = "image"
Integration in den Windows-Eigenschaftenspeicher

Manchmal werden in unterschiedlichen Metadaten-Schemata dieselben Metadaten-Eigenschaften bereitgestellt, häufig mit unterschiedlichen Eigenschaftsnamen. Wenn eine dieser Eigenschaften aktualisiert wird, die anderen aber nicht, können die Metadaten innerhalb der Datei asynchron werden. Der Windows Bildeigenschaft-Handler stellt die Standardimplementierung von IPropertyStore für Bilder bereit und wird von Anwendungen sowie von der Windows Vista Fotogalerie und dem Windows Explorer verwendet, um sicherzustellen, dass alle Metadaten in einem Bild synchron bleiben, und dass die von Anwendungen angezeigten Eigenschaften konsistent zu denjenigen sind, die von der Windows Vista Fotogalerie und dem Windows Explorer angezeigt werden. Wenn der Bildeigenschaft-Handler Metadaten aktualisiert, stellt er sicher, dass diese Eigenschaften konsistent über alle in der Datei vorhandenen gemeinsamen Metadaten-Formate aktualisiert werden.

Dazu muss der Bildeigenschaft-Handler das Container-Format kennen und wissen, wie er die verschiedenen darin enthaltenen Eigenschaften findet. Im Allgemeinen ist es für den Bildeigenschaft-Handler nicht möglich, zu erkennen, wie die verschiedenen Metadaten-Blöcke in einem proprietären Container-Format aussehen, aber wenn die Metadaten in Ihrem Container-Format genauso aussehen wie die Metadaten in einem TIFF-Container-Format oder in einem JPEG-Container-Format, kann der Bildeigenschaft-Handler dieses Wissen nutzen, um die Metadaten auch in Ihrem Container-Format konsistent zu aktualisieren.

Sie können die Zuordnung registrieren, indem Sie den folgenden Registrierungseintrag erstellen. Dieser Eintrag benachrichtigt den Bildeigenschaft-Handler darüber, dass das von dieser GUID bezeichnete Container-Format dieselben Pfade für die Metadaten-Abfragesprache versteht wie das Container-Format mit der GUID 163bcc30-e2e9-4f0b-961d-a3e9fdb788a3. (163bcc30-e2e9-4f0b-961d-a3e9fdb788a3 ist die GUID für das TIFF-Container-Format.)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ PhotoPropertyHandler\ContainerAssociations,{Container-Format GUID} = {163bcc30-e2e9-4f0b-961d-a3e9fdb788a3}

Der folgende Eintrag ordnet die Standardimplementierung von IPropertyStore des Bildeigenschaft-Handlers Dateien mit der Dateinamenerweiterung „.ext“ zu. Die erste GUID ist die ID der Schnittstelle IPropertyStore, und die zweite ist die GUID der Implementierung, die der Bildeigenschaft-Handler davon verwendet.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.ext,(Default) = "{a38b883c-1682-497e-97b0-0a3a9e801682}"

CODECs, die ein proprietäres Format verwenden, das nicht mit dem TIFF- oder dem JPEG-Container-Format kompatibel ist, müssen ihre eigene IPropertyStore-Implementierung schreiben.

Integration in die Windows Vista Fotogalerie

Windows Vista hat eine neue Bildanzeige, die auf WIC basiert, und die jedes WIC-fähige Format anzeigen kann, für das ein CODEC installiert ist. Um Windows Vista mitzuteilen, dass Ihr Bildformat in der neuen Bildanzeige geöffnet werden kann, müssen Sie eine Dateizuordnung dafür erstellen. Dazu legen Sie die folgenden Registrierungseinträge an.

HKEY_CLASSES_ROOT\.ext,(Default) = "ProgID" (e.g.extfile)
HKEY_CLASSES_ROOT\.ext\OpenWithProgids,ProgID 
HKEY_CLASSES_ROOT\.ext\OpenWithList\PhotoViewer.dll
HKEY_CLASSES_ROOT\.ext\ShellEx\ContextMenuHandlers\ShellImagePreview, (Default) = "{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"

HKEY_CLASSES_ROOT\SystemFileAssociations\.ext\OpenWithList\PhotoViewer.dll
HKEY_CLASSES_ROOT\SystemFileAssociations\.ext\ShellEx\ContextMenuHandlers\ ShellImagePreview,(Default) = "{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"

HKEY_CLASSES_ROOT\Image Format ProgID,(Default) = "Name des Bildformats"
HKEY_CLASSES_ROOT\Image Format ProgID\DefaultIcon,(Default) = "Pfad zum Symbol für den Dateityp/ Symbol-Index"

HKEY_CLASSES_ROOT\Bildformat-ProgID\shell\open\command,(Default) ="%SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Gallery\PhotoViewer.dll", ImageView_Fullscreen %1"

HKEY_CLASSES_ROOT\Bildformat-ProgID\shell\open,MuiVerb = "@%PROGRAM_FILES%\Windows Photo Gallery\photoviewer.dll,-3043"

HKEY_CLASSES_ROOT\Bildformat-ProgID\shell\open\DropTarget,Clsid = "{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"

HKEY_CLASSES_ROOT\Bildformat-ProgID\shell\printto\command,(Default) = "%SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Gallery\PhotoViewer.dll", ImageView_PrintTo /pt "%1" "%2" "%3" "%4"

Die ProgID ist normalerweise die Dateinamenerweiterung, der das Wort „file“ angefügt wird. (Ist die Dateinamenerweiterung beispielsweise .foo, wäre die ProgId normalerweise „foofile“.)

Es gibt noch andere Standard-Registrierungseinträge, die Sie für Dateizuordnungen vornehmen müssen, aber weil sie nicht spezifisch für WIC oder Windows Vista sind, gehen sie über den Rahmen dieses Artikels hinaus. Weitere Informationen über Dateizuordnungen finden Sie in der Dokumentation des Windows SDK.

Integration in den Windows Vista Miniaturansicht-Cache

Die beiden folgenden Einträge zeigen an, dass für das Laden von Miniaturansichten für Dateien mit dieser Dateinamenerweiterung die standardmäßige Implementierung für den WIC-Miniaturansicht-Provider genutzt werden kann. Die erste GUID ist die ID der Schnittstelle IThumbnailProvider, und die zweite ist die GUID der standardmäßigen Windows Vista-Implementierung dieser Schnittstelle. (Alle Einträge unter HLCR\.ext\ShellEx\ werden unter HKCR\SystemFileAssociations\.ext\ShellEx\ wiederholt.)

HKEY_CLASSES_ROOT\.ext\ShellEx\{e357fccd-a995-4576-b01f-234630154e96},(Default) = "{C7657C4A-9F68-40fa-A4DF-96BC08EB3551}"

HKEY_CLASSES_ROOT\SystemFileAssociations\.ext\ ShellEx\{e357fccd-a995-4576-b01f-234630154e96},(Default) = "{C7657C4A-9F68-40fa-A4DF-96BC08EB3551}"

Ihren CODEC installieren und deinstallieren

Neben der Registrierung Ihres CODEC muss Ihr Installationsprogramm auch in der Lage sein, den Miniaturansicht-Cache zu aktualisieren, um ihn darüber zu informieren, dass ein neuer CODEC zur Verfügung steht, und sicherzustellen, dass Ihr Decoder für das Extrahieren von Miniaturansichten verwendet wird, die sich bereits auf Ihrem Computer befinden.

Bei der Installation Ihres CODECs den Miniaturansicht-Cache aktualisieren

Bei der Installation eines CODECs muss das Installationsprogramm das folgende Windows API aufrufen, nachdem es seine Registrierungseinträge vorgenommen hat.

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL)

Dieser Aufruf teilt Windows mit, dass neue Informationen über Dateizuordnungen zur Verfügung stehen. Wenn es bereits Bilder in Ihrem Dateiformat auf dem Computer gibt, enthält der Miniaturansicht-Cache dafür Standard-Miniaturansichten, weil es keinen Decoder gab, der die Miniaturansichten extrahieren konnte, als die Bilder zum ersten Mal abgerufen wurden. Wenn Sie Windows mitteilen, dass eine neue Dateizuordnung zur Verfügung steht, verwirft der Miniaturansicht-Cache alle leeren Miniaturansichten und extrahiert die tatsächlichen Miniaturansichten aus den Dateien, die jetzt decodiert werden können.

Ihren CODEC deinstallieren

Wenn Sie eine Komponente deinstallieren, deinstallieren Sie normalerweise alle Abhängigkeiten, die Sie dafür eingerichtet haben. Bei WIC ist dies nicht der Fall.

Wenn Sie die verteilbare Windows Imaging Component herunterladen, müssen Sie eine Lizenzbedingung akzeptieren, die besagt, dass Sie WIC nie deinstallieren dürfen. Der Grund dafür ist, dass WIC eine Systemkomponente ist, von der viele installierte Anwendungen abhängig sind. Weil es sich bei WIC um eine Systemkomponente handelt, gibt es zu jedem Zeitpunkt nur eine Instanz davon. Wenn eine Komponente oder Anwendung sie also deinstallieren würde, würden alle Anwendungen auf dem Computer, die von ihr abhängig sind, nicht mehr funktionieren.

Der einzige Grund dafür, warum ein Deinstallationsprogramm im WIC-Paket enthalten ist, ist es, den Endbenutzern zu erlauben, es mit dem Dienstprogramm Programme ändern oder entfernen in der Systemsteuerung zu deinstallieren.

Achtung:   Ein CODEC oder eine Anwendung sollten unter keinen Umständen je die Windows Imaging Component deinstallieren.

Benutzern Ihren WIC-fähigen CODEC zur Verfügung stellen

Wenn Sie ein Kamerahersteller sind, können Sie Ihre Rohdaten-CODECs zusammen mit Ihren Kameras weitergeben. Sie können Ihre CODECs auch als Download auf Ihrer Website anbieten. Wenn ein Benutzer jedoch eine Bilddatei in Ihrem Format von einer anderen Quelle erhält, wie beispielsweise von einem Freund oder von einem Geschäftspartner, oder von irgendeiner andere Website, weiß er nicht unbedingt, woher er den CODEC für die Decodierung des Bildes erhalten kann.

Um bei der Lösung dieses Problems zu helfen, bietet Windows Vista eine einfachere Möglichkeit für die Benutzer Ihres Bildformats, Ihren CODEC zu finden und ihn auf ihre Computer herunterzuladen. Wenn die Windows Vista Fotogalerie eine Dateinamenerweiterung als Bildformat erkennt und der CODEC für dieses Format nicht installiert ist, zeigt sie dem Benutzer einen Dialog an, der ihn darüber informiert, dass das Foto nicht angezeigt werden kann, und fragt, ob er die für die Anzeige erforderliche Software herunterladen will. Stimmt der Benutzer zu, wird er auf eine von Microsoft verwaltete Website weitergeleitet, die einen Link auf die Download-Seite des CODEC-Herstellers enthält. (Optional können Sie auch anfordern, dass der Benutzer direkt auf Ihre Download-Seite weitergeleitet wird.)

Wenn Sie möchten, dass die Windows Vista Fotogalerie die Dateinamenerweiterungen Ihres Bildformats erkennt, so dass die Benutzer auf Ihre Download-Seite weitergeleitet werden können, gehen Sie wie folgt vor:

  1. Stellen Sie eine Download-Seite für Ihren CODEC bereit. (Sie können für jeden von Ihnen bereitgestellten CODEC eine separate Seite anlegen oder eine Seite mit Downloads für alle Ihre CODECs erstellen.)

    • Die Download-Seite sollte lokalisiert und einfach nach Kameramodellen zu durchsuchen sein.

  2. Stellen Sie Microsoft eine Liste der Dateinamenerweiterungen für Ihre Bildformate bereit, ebenso wie die URL(s) für Ihre Download-Seite(n).

Sie müssen Microsoft über die Dateinamenerweiterungen von zukünftig entwickelten neuen CODECS informieren, und ebenso über alle Änderungen der URL(s) für Ihre Download-Seiten, so dass der Fotogalerie die neue Information hinzugefügt werden kann.

Schlussbemerkung

Wenn Sie Ihren CODEC auf der Windows Imaging Component-Plattform erstellen, ist es möglich, dass alle auf WIC basierten Anwendungen dieselbe Plattformunterstützung für Ihr Bildformat erhalten wie für die allgemeinen Bildformate, die zusammen mit der Plattform bereitgestellt werden. Außerdem wird es damit der Windows Vista Fotogalerie, dem Explorer und der Bildanzeige möglich, Miniaturansichten sowie Vorschauen für Bilder in Ihrem Format unter Verwendung des von Ihnen bereitgestellten Decoders anzuzeigen. Für Rohdatenformate ermöglicht es fortgeschritteneren Bildverarbeitungsanwendungen, die Rohdaten-Verarbeitungsfunktionen Ihres Decoders zu nutzen. Abhängig von den von Ihnen unterstützten Encoder-Optionen können Sie spezielle Funktionen Ihres Encoders bereitstellen, um die fortgeschrittenen Funktionen Ihres Bildformats voll nutzen zu können.

Für die Entwicklung eines WIC-fähigen CODECs müssen Sie einige neue Schnittstellen implementieren. Häufig können Sie einen Wrapper für Ihren vorhandenen CODEC schreiben, der diese Schnittstellen implementiert. Wenn Sie Ihren CODEC installieren, müssen Sie verschiedene Registrierungseinträge vornehmen, damit die WIC-Plattform Ihren CODEC erkennen kann, und ihm die geeigneten Metadaten-Handler zuordnet. Außerdem müssen Sie ein API aufrufen, um den Miniaturansicht-Cache von (leeren) Standard-Miniaturansichten zu befreien, die möglicherweise den Bildern in Ihrem Format zuvor zugeordnet wurden. Wenn Sie möchten, können Sie der Windows Vista Fotogalerie ermöglichen, den Benutzern einen Link für den Download Ihres CODECs bereitzustellen, wenn die Fotogalerie auf ein Bild mit Ihrer Dateinamenerweiterung trifft. Dazu müssen Sie Microsoft Informationen über die Dateinamenerweiterung Ihres CODECs bereitstellen, ebenso wie die URL für Ihre Download-Seite.

Die Entwicklung von CODECs auf der WIC-Plattform bietet wesentliche Vorteile für die Benutzer Ihres Bildformats und macht es für Anwendungen von Drittanbietern einfach, Ihr Bildformat ebenfalls zu unterstützen.


Anzeigen: