Implementieren von IWICBitmapEncoder

IWICBitmapEncoder

Diese Schnittstelle ist das Gegenstück zur IWICBitmapDecoder-Schnittstelle und der Ausgangspunkt für die Codierung einer Bilddatei. Genauso wie IWICBitmapDecoder zum Abrufen von Eigenschaften auf Containerebene und einzelnen Frames aus dem Imagecontainer verwendet wird, wird IWICBitmapEncoder zum Festlegen von Eigenschaften auf Containerebene und Serialisieren einzelner Bildframes in den Container verwendet. Sie implementieren diese Schnittstelle in Ihrer Encoderklasse auf Containerebene.

interface IWICBitmapEncoder : public IUnknown
{
   // Required methods
   HRESULT Initialize ( IStream *pIStream,
              WICBitmapEncoderCacheOption cacheOption );
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetEncoderInfo ( IWICBitmapEncoderInfo **pIEncoderInfo );
   HRESULT CreateNewFrame ( IWICBitmapFrameEncode **ppIFrameEncode,
              IPropertyBag2 **ppIEncoderOptions );
   HRESULT Commit ( void );

   // Optional methods
   HRESULT SetPreview ( IWICBitmapSource *pIPreview );
   HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
   HRESULT SetColorContexts ( UINT cCount,
              IWICColorContext **ppIColorContext );
   HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter 
              **ppIMetadataQueryWriter );
   HRESULT SetPalette ( IWICPalette *pIPalette);
};

Wie unter Implementieren von IWICBitmapDecodererläutert, verfügen einige Bildformate über globale Miniaturansichten, Farbkontexte oder Metadaten, während viele Bildformate diese nur pro Frame bereitstellen. Daher sind die Methoden zum Festlegen dieser für IWICBitmapEncoderoptional, sind jedoch für IWICBitmapFrameEncode erforderlich. Die Methoden, die für IWICBitmapEncoder optional sind, werden im Abschnitt zu IWICBitmapFrameEncode erläutert, wo sie am häufigsten implementiert werden.

Wenn Sie keine globalen Miniaturansichten unterstützen, geben Sie WINCODEC _ ERR _ CODECNOTHUMBNAIL von der SetThumbnail-Methode auf IWICBitmapEncoder zurück. Wenn Sie eine Palette auf Containerebene nicht unterstützen oder wenn das bild, das Sie codieren, kein indiziertes Format hat, geben Sie WINCODEC ERR PALETTEUNAVAILABLE von der _ _ SetPalette-Methode zurück. Geben Sie für alle anderen nicht unterstützten Methoden WINCODEC _ ERR _ UNSUPPORTEDOPERATION zurück.

Initialisieren

Initialize ist die erste Methode, die für einen IWICBitmapEncoder aufgerufen wird, nachdem er instanziiert wurde. Ein Bildstream wird an den Encoder übergeben, und ein Aufrufer kann optional eine Cacheoption angeben. Im Fall des Decoders ist der Stream schreibgeschützt, aber der an einen Encoder übergebene Stream ist ein schreibbarer Stream, in den der Encoder alle Bilddaten und Metadaten serialisiert. Die Cacheoptionen auf dem Encoder unterscheiden sich auch.

enum WICBitmapEncoderCacheOption
{
   WICBitmapEncoderCacheInMemory,
   WICBitmapEncoderCacheTempFile,
   WICBitmapEncoderNoCache
}

Die Anwendung kann den Encoder so anfordern, dass die Bilddaten im Arbeitsspeicher zwischengespeichert, in einer temporären Datei zwischengespeichert oder ohne Zwischenspeicherung direkt in die Datenträgerdatei geschrieben werden. Wenn der Encoder aufgefordert wird, die Daten in einer temporären Datei zwischenspeichern zu müssen, sollte er eine temporäre Datei auf dem Datenträger erstellen und direkt in diese Datei schreiben, ohne im Arbeitsspeicher zwischenspeichern zu müssen. Wenn der Aufrufer die Option Kein Cache auswählt, muss jeder Frame in der Reihenfolge, in der er erstellt werden kann, in der Reihenfolge, in der er erstellt werden kann.

GetContainerFormat

GetContainerFormat wird auf die gleiche Weise wie die GetContainerFormat-Methode in Implementing IWICBitmapDecoder implementiert.

GetEncoderInfo

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

Siehe das Beispiel unter Implementieren von IWICBitmapDecoder unter GetDecoderInfo.

CreateNewFrame

CreateNewFrame ist das Encoder-Pendant von GetFrame auf IWICBitmapDecoder. Diese Methode gibt ein IWICBitmapFrameEncode-Objekt zurück. Dabei handelt es sich um das Objekt, das die Bilddaten tatsächlich für einen bestimmten Frame im Container serialisiert.

Einer der Vorteile von Windows Imaging Component (WIC) ist, dass sie eine Abstraktionsebene für Anwendungen bietet, die es ihnen ermöglicht, mit allen Bildformaten auf die gleiche Weise zu arbeiten. Allerdings sind nicht alle Bildformate identisch. Einige Bildformate verfügen über Funktionen, die andere nicht haben. Damit Anwendungen diese einzigartigen Funktionen nutzen können, ist es erforderlich, dem Codec eine Möglichkeit zu bieten, sie verfügbar zu machen. Dies ist der Zweck von Encoderoptionen. Wenn Ihr Codec Encoderoptionen unterstützt, sollten Sie ein IPropertyBag2-Objekt erstellen, das die von Ihnen unterstützten Encoderoptionen verfügbar macht, und es im ppIEncoderOptions-Parameter dieser Methode zurückgeben. Der Aufrufer kann dann dieses IPropertyBag2-Objekt verwenden, um zu bestimmen, welche Encoderoptionen Ihr Codec unterstützt. Wenn der Aufrufer Werte für eine der unterstützten Encoderoptionen angeben möchte, weist er den Wert der relevanten Eigenschaft im IPropertyBag2-Objekt zu und über gibt ihn an das neu erstellte IWICBitmapFrameEncode-Objekt in seiner Initialize-Methode weiter.

Um ein IPropertyBag2-Objekt zu instanziieren, müssen Sie zunächst eine PROPBAG2-Struktur erstellen, um jede Encoderoption anzugeben, die Ihr Encoder unterstützt, und ihren Datentyp für jede Eigenschaft anzugeben. Anschließend müssen Sie ein IPropertyBag2-Objekt implementieren, das die Wertbereiche für jede Eigenschaft beim Schreiben erzwingt und alle in Konflikt stehenden oder überlappenden Werte abgleicht. Für einfache Sätze von Encoderoptionen ohne Konflikt können Sie die CreateEncoderPropertyBag-Methode aufrufen, die ein einfaches IPropertyBag2-Objekt mit den Eigenschaften erstellt, die Sie in Ihrer PROPBAG2-Struktur angeben. Sie müssen die Wertbereiche weiterhin erzwingen. Für erweiterte Encoderoptionen oder wenn Sie in Konflikt stehende Werte abstimmen müssen, sollten Sie Ihre eigene IPropertyBag2-Implementierung schreiben.

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

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

hr = pComponentFactory->CreateEncoderPropertyBag( 
   pPropBagOptions, cuiPropertyCount, &pPropertyBag);

WIC bietet eine kleine Reihe kanonischer Encoderoptionen, die von einigen der gängigen Bildformate verwendet werden. Alle kanonischen Encoderoptionen sind optional, und Codecs sind nicht erforderlich, um sie zu unterstützen. Sie werden als kanonische Optionen bereitgestellt, weil viele Anwendungen die Benutzeroberfläche für Benutzer verfügbar machen, um diese Optionen anzugeben, wenn eine Bilddatei in einem Format gespeichert wird, das sie unterstützt. Die Bereitstellung einer kanonischen Möglichkeit, diese Optionen anzugeben, erleichtert es Anwendungen, sie auf konsistente Weise mit Encodern zu kommunizieren. Die kanonischen Encoderoptionen sind in der folgenden Tabelle aufgeführt.

Encoderoption VARTYPE Wertbereich
Lossless VT _ BOOL TRUE/FALSE
ImageQuality VT _ R4 0.0-1.0
CompressionQuality VT _ R4 0.0-1.0
BitmapTransform VT _ UI1 WICBitmapTransformOptions

Wenn Ihr Codec verlustfreie Codierung unterstützt, sollten Sie die Lossless-Encoderoption verfügbar machen, damit Anwendungen anfordern können, dass ein Bild verlustfrei codiert wird. Wenn ein Aufrufer diese Eigenschaft auf True setzt, sollten Sie die ImageQuality-Option ignorieren und das Bild verlustfrei codieren.

Mit der Option ImageQuality kann eine Anwendung den Genauigkeitsgrad angeben, mit dem das Bild codiert werden soll. Mit dieser Option kann ein Benutzer einen Kompromiss zwischen der Imagequalität und der Geschwindigkeit und/oder Dateigröße treffen. JPEG ist ein Beispiel für ein Bildformat, das diesen Kompromiss unterstützt. Der Wert 0,0 gibt an, dass Die Genauigkeit von geringer Wichtigkeit ist und der Encoder seinen verlustreichsten Algorithmus verwenden sollte. Der Wert 1.0 gibt an, dass Die Genauigkeit am wichtigsten ist und der Encoder die höchstmögliche Genauigkeit beibehalten sollte. (Je nach Codec kann dies mit der Option Verlustlos synonym sein. Wenn Ihr Codec jedoch verlustfreie Codierung unterstützt und die Option Verlustlos auf True festgelegt ist, sollte die ImageQuality-Option ignoriert werden.)

Mit der Option CompressionQuality kann eine Anwendung die Effizienz der Komprimierung angeben, die beim Codieren des Bilds verwendet werden soll. Ein sehr effizienter Algorithmus erzeugt möglicherweise eine kleinere Bilddatei mit der gleichen Qualität wie ein weniger effizienter Komprimierungsalgorithmus, die Codierung kann jedoch länger dauern. Mit dieser Option kann ein Benutzer einen Kompromiss zwischen der Dateigröße und der Geschwindigkeit der Codierung angeben und dabei die gleiche Qualität beibehalten. TIFF ist ein Beispiel für ein Bildformat, das diesen Kompromiss unterstützt. (Beachten Sie, dass ein Format wie JPEG unterschiedliche Komprimierungsstufen unterstützt, aber eine höhere Komprimierungsrate zu einer niedrigeren Bildqualität führt. Daher würde ein JPEG-Bildformat die Option ImageQuality anstelle der CompressionQuality-Option verfügbar machen.) Der Wert 0,0 für diese Option gibt an, dass Sie das Bild so schnell wie möglich komprimieren sollten, ohne die Genauigkeit zu verringern, auf Kosten einer größeren Dateigröße. Der Wert 1.0 gibt an, dass Sie die kleinst mögliche Dateigröße (mit der gleichen Qualitätsstufe) erstellen sollten, unabhängig davon, wie lange die Codierung dauern kann. Ein Codec kann sowohl die ImageQuality-Option als auch die CompressionQuality-Option unterstützen, wobei die ImageQuality-Option den akzeptablen Grad an Verlust angibt und die Option CompressionQuality einen Kompromiss zwischen Größe und Geschwindigkeit auf der angegebenen Qualitätsebene bietet.

Die BitmapTransform-Option bietet dem Aufrufer eine Möglichkeit, einen Drehwinkel oder eine vertikale oder horizontale Flip-Ausrichtung bei der Codierung anzugeben. Die WICBitmapTransformOptions-Enum, die zum Angeben der angeforderten Transformation verwendet wird, ist die gleiche Enum, die beim Anfordern einer Transformation während der Decodierung über die IWICBitmapSourceTransform-Schnittstelle verwendet wird.

Beachten Sie, dass Encoder nicht auf die kanonischen Encoderoptionen beschränkt sind. Der Zweck von Encoderoptionen besteht in der Aktivierung, dass Encoder ihre Funktionen verfügbar machen können, und es gibt keine Beschränkung für die Arten von Funktionen, die Sie verfügbar machen können. Stellen Sie sicher, dass Ihre Encoderoptionen gut dokumentiert sind. Obwohl eine Anwendung den Eigenschaftentüte verwenden kann, den Sie von dieser Methode zurückgeben, um die Namen, Typen und Wertebereiche für die von Ihnen unterstützten Optionen zu finden, können sie ihre Bedeutungen nur in Ihrer Dokumentation herausfinden oder sie auf der Benutzeroberfläche verfügbar machen.

Commit

Commit ist die Methode, die Sie aufrufen, nachdem alle Bilddaten und Metadaten in den Stream serialisiert wurden. Sie sollten diese Methode verwenden, um die Vorschaubilddaten in den Stream und ggf. globale Miniaturansichten, Metadaten, Paletten oder andere Elemente zu serialisieren. Diese Methode sollte den Dateistream nicht schließen, da von der Anwendung, die den Stream geöffnet hat, erwartet wird, dass er geschlossen wird.

Der Abschnitt der IWICBitmapFrameEncode:Commit-Methode enthält Details dazu, wie sich DIE IWICBitmapEncoderCacheOptions auf das Verhalten dieser Methode auswirken.

SetPreview

SetPreview wird verwendet, um eine Vorschau des Images zu erstellen. Es ist zwar nicht zwingend erforderlich, dass jedes Image über eine Vorschauversion verfügen muss, es wird jedoch dringend empfohlen. Moderne Digitalkameras und Scanner generieren bilder mit sehr hoher Auflösung, die in der Regel sehr groß sind und daher eine erhebliche Verarbeitungszeit für die Decodierung inne haben. Bilder der nächsten Generation von Kameras werden noch größer sein. Es ist eine gute Idee, eine kleinere Version eines Bilds mit niedrigerer Auflösung (in der Regel im JPEG-Format) zur Verfügung zu stellen, die schnell decodiert und "sofort" angezeigt werden kann, wenn ein Benutzer es an fordert. Eine Anwendung kann eine Vorschau anfordern, bevor sie die Decodierung des eigentlichen Bilds angibt, um benutzern eine bessere Benutzererfahrung zu bieten, und ihnen eine Darstellung des Bilds in Bildschirmgröße anzeigen, während sie darauf warten, das tatsächliche Bild zu decodieren. Codecs sollten zwar Vorschauen bereitstellen, Codecs, die IWICBitmapSourceTransform nicht unterstützen, sollten dies jedoch definitiv tun.

Wenn Sie eine JPEG-Vorschau bereitstellen, müssen Sie keinen JPEG-Encoder schreiben, um ihn zu codieren. Sie sollten an den JPEG-Encoder delegieren, der mit der WIC-Plattform für die Codierung von Vorschauversionen und Miniaturansichten enthalten ist.

Referenz

IWICBitmapEncoder

IWICBitmapFrameEncode

Konzept

Encoderschnittstellen

Implementieren von IWICBitmapCodecProgressNotification (Encoder)

Schreiben eines WIC-Enabled CODEC

Windows Übersicht über Bildverarbeitungskomponenten