Implementieren von IWICBitmapDecoder

Iwicbitmapdecoder

Wenn eine Anwendung einen Decoder anfordert, erfolgt der erste Interaktionspunkt mit dem Codec über die IWICBitmapDecoder-Schnittstelle . Dies ist die Schnittstelle auf Containerebene, die Zugriff auf die Eigenschaften der obersten Ebene des Containers und vor allem auf die darin enthaltenen Frames bietet. Dies ist die primäre Schnittstelle ihrer Decoderklasse auf Containerebene.

interface IWICBitmapDecoder : IUnknown
{
// Required methods
   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 );

// Optional methods
   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 verfügen über globale Miniaturansichten, Farbkontexte oder Metadaten, während viele Bildformate diese nur pro Bild bereitstellen. Die Methoden für den Zugriff auf diese Elemente sind in IWICBitmapDecoder optional, aber für IWICBitmapFrameDecode erforderlich. Ebenso verwenden einige Codecs keine indizierten Pixelformate und müssen daher die CopyPalette-Methoden nicht auf beiden Schnittstellen implementieren. Weitere Informationen zu den optionalen IWICBitmapDecoder-Methoden finden Sie unter Implementieren von IWICBitmapFrameDecode, wo sie am häufigsten implementiert werden.

QueryCapability

QueryCapability ist die Methode, die für die Codecverschiedung verwendet wird. (Siehe Ermittlung und Schiedsverfahren im Thema Funktionsweise der Windows-Bildverarbeitungskomponente ). Wenn zwei Codecs in der Lage sind, dasselbe Bildformat zu decodieren, oder wenn eine Musterkollision auftritt, bei der zwei Codecs das gleiche Identifizierungsmuster verwenden, können Sie mit dieser Methode den Codec auswählen, der am besten für ein bestimmtes Bild geeignet ist.

Beim Aufrufen dieser Methode übergibt Die Windows-Bildverarbeitungskomponente (WIC) den tatsächlichen Stream, der das Image enthält. Sie müssen überprüfen, ob Sie jeden Frame innerhalb des Bilds decodieren und die Metadatenblöcke auflisten können, um genau zu deklarieren, welche Funktionen dieser Decoder in Bezug auf den spezifischen Dateistream hat, der an ihn übergeben wird. Dies ist für alle Decoder wichtig, aber besonders wichtig für Bildformate, die auf Tagged Image File Format (TIFF)-Containern basieren. Der Ermittlungsprozess funktioniert, indem Muster, die Decodern in der Registrierung zugeordnet sind, mit Mustern in der tatsächlichen Imagedatei abgleichen. Wenn Sie Ihr Identifikationsmuster in der Registrierung deklarieren, wird sichergestellt, dass Ihr Decoder immer für Bilder im Bildformat erkannt wird. Ihr Decoder konnte jedoch weiterhin für Bilder in anderen Formaten erkannt werden. Beispielsweise enthalten alle TIFF-Container das TIFF-Muster, bei dem es sich um ein gültiges Identifizierungsmuster für das TIFF-Bildformat handelt. Dies bedeutet, dass während der Ermittlung mindestens zwei Identifizierende Muster in Bilddateien für jedes Bildformat gefunden werden, das auf einem Container im TIFF-Stil basiert. Das eine ist das TIFF-Muster, das andere das tatsächliche Bildformatmuster. Obwohl es weniger wahrscheinlich ist, kann es auch zu Musterkollisionen zwischen anderen nicht verwandten Bildformaten kommen. Aus diesem Grund sind Ermittlungen und Schiedsverfahren ein zweistufiger Prozess. Vergewissern Sie sich immer, dass der an QueryCapability übergebene Bilddatenstrom tatsächlich ein gültiger instance Ihres eigenen Bildformats ist. Wenn Ihr Codec außerdem ein Bildformat decodiert, für das Sie die Spezifikation nicht besitzen, sollte Ihre QueryCapability-Implementierung überprüfen, ob ein Feature vorhanden ist, das möglicherweise unter der Bildformatspezifikation gültig ist, die Ihr Codec nicht implementiert. Dadurch wird sichergestellt, dass benutzer keine unnötigen Decodierungsfehler auftreten oder unerwartete Ergebnisse mit Ihrem Codec erhalten.

Bevor Sie einen Vorgang für das Image ausführen, müssen Sie die aktuelle Position des Datenstroms speichern, damit Sie ihn an seiner ursprünglichen Position wiederherstellen können, bevor Sie von der -Methode zurückkehren. Die WICBitmapDecoderCapabilities-Enumeration , die die Funktionen angibt, wird wie folgt definiert:

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

Sie sollten WICBitmapDecoderCapabilitySameEncoder nur deklarieren, wenn Ihr Encoder derjenige war, der das Bild codiert hat. Nachdem Sie überprüft haben, ob Sie jeden Frame im Container decodieren können, deklarieren Sie entweder WICBitmapDecoderCapabilityCanDecodeSomeImages , wenn Sie einige, aber nicht alle Frames decodieren können, WICBitmapDecoderCapabilityCanDecodeAllImages , wenn Sie alle Frames decodieren können, oder keines, wenn Sie keines davon decodieren können. (Diese beiden Enumerationen schließen sich gegenseitig aus. Wenn Sie WICBitmapDecoderCapabilityCanDecodeAllImages zurückgeben, wird WICBitmapDecoderCapabilityCanDecodeSomeImages ignoriert.) Deklarieren Sie WICBitmapDecoderCapabilityCanEnumerateMetadata , nachdem Sie überprüft haben, dass Sie die Metadatenblöcke im Imagecontainer auflisten können. Sie müssen nicht in jedem Frame nach einer Miniaturansicht suchen. Wenn eine globale Miniaturansicht vorhanden ist und Sie sie decodieren können, können Sie WICBitmapDecoderCapabilityCanDecodeThumbnail deklarieren. Wenn keine globale Miniaturansicht vorhanden ist, versuchen Sie, die Miniaturansicht für Frame 0 zu decodieren. Wenn an einer dieser Stellen keine Miniaturansicht vorhanden ist, deklarieren Sie diese Funktion nicht.

Nachdem Sie die Funktionen des Decoders in Bezug auf den an diese Methode übergebenen Bilddatenstrom bestimmt haben, führen Sie einen OR-Vorgang mit den WICBitmapDecoderCapabilities aus, die Sie überprüft haben, ob dieser Decoder für dieses Bild ausführen kann, und geben Sie das Ergebnis zurück. Denken Sie daran, den Stream an seiner ursprünglichen Position wiederherzustellen, bevor sie zurückgegeben werden.

Initialize

Initialisieren wird von einer Anwendung aufgerufen, nachdem ein Decoder zum Decodieren eines bestimmten Bilds ausgewählt wurde. Der Bilddatenstrom wird an den Decoder übergeben, und ein Aufrufer kann optional die Cacheoption WICDecodeOptions für den Umgang mit den Metadaten in der Datei angeben.

enum WICDecodeOptions
{
   WICDecodeMetadataCacheOnDemand,
   WICDecodeMetadataCacheOnLoad
}

Einige Anwendungen verwenden Metadaten mehr als andere. Die meisten Anwendungen müssen nicht auf alle Metadaten in einer Bilddatei zugreifen und fordern bei Bedarf bestimmte Metadaten an. Andere Anwendungen würden lieber alle Metadaten im Voraus zwischenspeichern, als den Dateistream geöffnet zu halten und jedes Mal Datenträger-E/A durchzuführen, wenn sie auf Metadaten zugreifen müssen. Wenn der Aufrufer keine Metadatencacheoption angibt, sollte das Zwischenspeicherungsverhalten bei Bedarf zwischengespeichert werden. Dies bedeutet, dass keine Metadaten in den Arbeitsspeicher geladen werden sollten, bis die Anwendung eine bestimmte Anforderung für diese Metadaten stellt. Wenn die Anwendung WICDecodeMetadataCacheOnLoad angibt, sollten die Metadaten sofort in den Arbeitsspeicher geladen und zwischengespeichert werden. Wenn Metadaten beim Laden zwischengespeichert werden, wird der Dateistream möglicherweise freigegeben, nachdem die Metadaten zwischengespeichert wurden.

GetContainerFormat

Um GetContainerFormat zu implementieren, geben Sie einfach die GUID des Bildformats des Bilds zurück, für das der Decoder instanziiert ist. Diese Methode wird auch in IWICMetadataBlockReader und IWICBitmapEncoder implementiert.

GetDecoderInfo

GetDecoderInfo gibt ein IWICBitmapDecoderInfo-Objekt zurück. Um das IWICBitmapDecoderInfo-Objekt abzurufen, übergeben Sie einfach die GUID Ihres Decoders an die CreateComponentInfo-Methode auf IWICImagingFactory, und fordern Sie dann die IWICBitmapDecoderInfo-Schnittstelle darauf an, wie im folgenden Beispiel gezeigt.

IWICComponentInfo* pComponentInfo = NULL;
HRESULT hr;
 
hr = m_pImagingFactory->CreateComponentInfo(CLSID_This, &pComponentInfo);

hr = pComponentInfo->QueryInterface(IID_IWICBitmapDecoderInfo, (void**)ppIDecoderInfo);

GetFrameCount

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

Getframe

GetFrame ist eine wichtige Methode für die IWICBitmapDecoder-Schnittstelle , da der Frame die tatsächlichen Bildbits enthält und das von dieser Methode zurückgegebene Frame-Decoderobjekt das Objekt ist, das die tatsächliche Decodierung des angeforderten Bilds durchführt. Dies ist das andere Objekt, das Sie beim Schreiben eines Decoders implementieren müssen. Weitere Informationen zu Framedecodern finden Sie unter Implementieren von IWICBitmapFrameDecode.

GetPreview

GetPreview gibt eine Vorschau des Bilds zurück. Eine ausführliche Erläuterung der Vorschau finden Sie unter Implementieren der IWICBitmapEncoder-Methode auf der Implementieren von IWICBitmapEncoder-Schnittstelle .

Wenn Ihr Bildformat eine eingebettete JPEG-Vorschau enthält, wird dringend empfohlen, nicht einen JPEG-Decoder zum Decodieren zu schreiben, sondern an den JPEG-Decoder zu delegieren, der mit der WIC-Plattform zum Decodieren von Vorschau- und Miniaturansichten ausgeliefert wird. Suchen Sie hierzu den Anfang der Vorschaubilddaten im Stream, und rufen Sie die CreateDecoderFromStream-Methode auf der IWICImagingFactory auf.

IWICBitmapDecoder* pPreviewDecoder = NULL;
IWICBitmapFrameDecode* pPreviewFrame = NULL;
IWICBitmapSource* pPreview = NULL;
HRESULT hr;

hr = m_pImagingFactory->CreateDecoderFromStream(
                               m_pStream, NULL, 
                               WICDecodeMetadataCacheOnDemand, &pPreviewDecoder);
hr = pPreviewDecoder->GetFrame(0, pPreviewFrame);
hr = pPreviewFrame->QueryInterface(IID_IWICBitmapSource, (void**)&pPreview);

Referenz

Iwicbitmapdecoder

Iwicbitmapframedecode

Konzept

Decoderschnittstellen

Implementieren von IWICBitmapCodecProgressNotification (Decoder)

Schreiben eines WIC-Enabled CODEC

Übersicht über die Windows-Bildverarbeitungskomponente