Implementieren von IWICBitmapEncoder
IWICBitmapEncoder
Diese Schnittstelle ist das Pendant zur IWICBitmapDecoder-Schnittstelle und der Ausgangspunkt für die Codierung einer Bilddatei. Genau 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 zum 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 IWICBitmapDecoder erlä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 Optionen für IWICBitmapEncoder optional, aber für IWICBitmapFrameEncode erforderlich. Die in IWICBitmapEncoder optionalen Methoden 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 keine Palette auf Containerebene unterstützen oder das von Ihnen codierte Bild kein indiziertes Format aufweist, 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.
Initialize
Initialize ist die erste Methode, die auf einem IWICBitmapEncoder aufgerufen wird, nachdem sie instanziiert wurde. Ein Bilddatenstrom 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 beschreibbarer Datenstrom, in den der Encoder alle Bilddaten und Metadaten serialisiert. Die Cacheoptionen für den Encoder sind ebenfalls unterschiedlich.
enum WICBitmapEncoderCacheOption
{
WICBitmapEncoderCacheInMemory,
WICBitmapEncoderCacheTempFile,
WICBitmapEncoderNoCache
}
Die Anwendung hat die Wahl, den Encoder anzufordern, die Bilddaten im Arbeitsspeicher zwischenzuspeichern, sie in einer temporären Datei zwischenzuspeichern oder sie ohne Zwischenspeicherung direkt in die Datenträgerdatei zu schreiben. Wenn er aufgefordert wird, die Daten in einer temporären Datei zwischenzuspeichern, sollte der Encoder eine temporäre Datei auf dem Datenträger erstellen und direkt in diese Datei schreiben, ohne im Arbeitsspeicher zwischenzuspeichern. Wenn der Aufrufer die Option Kein Cache auswählt, muss jeder Frame in der Reihenfolge committet werden, bevor der nächste Frame erstellt werden kann.
GetContainerFormat
GetContainerFormat wird auf die gleiche Weise wie die GetContainerFormat-Methode in Implementieren von IWICBitmapDecoder implementiert.
GetEncoderInfo
GetEncoderInfo gibt ein IWICBitmapEncoderInfo-Objekt zurück. Um das IWICBitmapEncoderInfo-Objekt abzurufen, übergeben Sie einfach die GUID Ihres Encoders an die CreateComponentInfo-Methode auf IWICImagingFactory, und fordern Sie dann die IWICBitmapEncoderInfo-Schnittstelle darauf an.
Sehen Sie sich das Beispiel unter Implementieren von IWICBitmapDecoder unter GetDecoderInfo an.
CreateNewFrame
CreateNewFrame ist das Encoderentsprechen von GetFrame auf IWICBitmapDecoder. Diese Methode gibt ein IWICBitmapFrameEncode-Objekt zurück, bei dem es sich um das Objekt handelt, das die Bilddaten für einen bestimmten Frame innerhalb des Containers serialisiert.
Einer der Vorteile von Windows Imaging Component (WIC) besteht darin, dass sie eine Abstraktionsebene für Anwendungen bereitstellt, die es ihnen ermöglicht, mit allen Bildformaten auf die gleiche Weise zu arbeiten. Es sind jedoch nicht alle Bildformate identisch. Einige Bildformate verfügen über Funktionen, die andere nicht haben. Damit Anwendungen diese einzigartigen Funktionen nutzen können, muss dem Codec eine Möglichkeit zur Verfügung gestellt werden, 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 übergibt ihn an das neu erstellte IWICBitmapFrameEncode-Objekt in seiner Initialize-Methode.
Um ein IPropertyBag2-Objekt zu instanziieren, müssen Sie zunächst eine PROPBAG2-Struktur erstellen, um jede Vom Encoder unterstützte Encoderoption 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 sich überlappenden Werte abgleicht. Für einfache Sätze von Encoderoptionen, die nicht in Konflikt stehen, können Sie die CreateEncoderPropertyBag-Methode aufrufen, die ein einfaches IPropertyBag2-Objekt mithilfe der Eigenschaften erstellt, die Sie in Ihrer PROPBAG2-Struktur angeben. Sie müssen die Wertbereiche weiterhin erzwingen. Für erweiterte Encoderoptionen oder wenn Sie widersprüchliche Werte abgleichen müssen, sollten Sie Eine 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 von kanonischen Encoderoptionen, die von einigen gängigen Bildformaten verwendet werden. Alle kanonischen Encoderoptionen sind optional, und Codecs sind nicht erforderlich, um sie zu unterstützen. Der Grund, warum sie als kanonische Optionen bereitgestellt werden, liegt darin, dass viele Anwendungen die Benutzeroberfläche für Benutzer verfügbar machen, um diese Optionen beim Speichern einer Bilddatei in einem Format anzugeben, das sie unterstützt. Die Bereitstellung einer kanonischen Methode zum Angeben dieser Optionen erleichtert Es Anwendungen, sie konsistent mit Encodern zu kommunizieren. Die kanonischen Encoderoptionen sind in der folgenden Tabelle aufgeführt.
Encoderoption | VARTYPE | Wertbereich |
---|---|---|
Lossless | VT_BOOL | Wahr/falsch |
ImageQuality | VT_R4 | 0.0-1.0 |
CompressionQuality | VT_R4 | 0.0-1.0 |
BitmapTransform | VT_UI1 | WICBitmapTransformOptions |
Wenn Ihr Codec die verlustfreie Codierung unterstützt, sollten Sie die Option Verlustfreier Encoder verfügbar machen, um Anwendungen die verlustfreie Codierung eines Bilds anzufordern. Wenn ein Aufrufer diese Eigenschaft auf True festlegt, 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 Bildqualität und Geschwindigkeit und/oder Dateigröße machen. JPEG ist ein Beispiel für ein Bildformat, das diesen Kompromiss unterstützt. Der Wert 0,0 gibt an, dass die Genauigkeit von geringer Bedeutung ist und der Encoder seinen Verlustalgorithmus verwenden sollte. Der Wert 1,0 gibt an, dass die Genauigkeit am wichtigsten ist und der Encoder die höchstmögliche Genauigkeit beibehalten sollte. (Abhängig von Ihrem Codec kann dies gleichbedeutend mit der Option Verlustlos sein. Wenn Ihr Codec jedoch die verlustfreie Codierung unterstützt und die Option Verlustlos auf True festgelegt ist, sollte die Option ImageQuality 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, aber die Codierung kann länger dauern. Mit dieser Option kann ein Benutzer einen Kompromiss zwischen Dateigröße und Codierungsgeschwindigkeit angeben und dabei das gleiche Qualitätsniveau beibehalten. TIFF ist ein Beispiel für ein Bildformat, das diesen Kompromiss unterstützt. (Beachten Sie, dass ein Format wie JPEG verschiedene Komprimierungsstufen unterstützt, aber eine höhere Komprimierungsrate führt zu einer niedrigeren Bildqualität. Daher würde ein JPEG-Bildformat anstelle der CompressionQuality-Option die Option ImageQuality 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, und zwar auf Kosten einer größeren Dateigröße. Der Wert 1,0 gibt an, dass Sie unabhängig davon, wie lange die Codierung dauern kann, eine möglichst geringe Dateigröße (bei gleicher Qualität) erstellen sollten. Ein Codec kann sowohl die Option ImageQuality als auch die Option CompressionQuality unterstützen, wobei die Option ImageQuality den akzeptablen Grad an Verlust angibt, und die Option CompressionQuality bietet einen Kompromiss zwischen Größe und Geschwindigkeit auf der angegebenen Qualitätsstufe.
Die BitmapTransform-Option bietet dem Aufrufer eine Möglichkeit, beim Codieren einen Drehwinkel oder eine vertikale oder horizontale Flipausrichtung anzugeben. Die WICBitmapTransformOptions-Enumeration, die zum Angeben der angeforderten Transformation verwendet wird, ist dieselbe Enumeration, 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. Encoderoptionen dienen dazu, Encodern die Möglichkeit zu geben, ihre Funktionen verfügbar zu machen, und es gibt keine Beschränkung für die Typen von Funktionen, die Sie verfügbar machen können. Stellen Sie sicher, dass Ihre Encoderoptionen gut dokumentiert sind. Obwohl eine Anwendung den Eigenschaftenbehälter verwenden kann, den Sie von dieser Methode zurückgeben, um die Namen, Typen und Wertbereiche für die von Ihnen unterstützten Optionen zu ermitteln, ist die einzige Möglichkeit, ihre Bedeutung herauszufinden oder sie auf der Benutzeroberfläche verfügbar zu machen, in Ihrer Dokumentation.
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 zu serialisieren und ggf. globale Miniaturansichten, Metadaten, Paletten oder andere Elemente zu serialisieren. Diese Methode sollte den Dateidatenstrom 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 unbedingt erforderlich, dass jedes Bild eine Vorschau hat, aber es wird dringend empfohlen. Moderne Digitalkameras und Scanner erzeugen sehr hochauflösende Bilder, die in der Regel sehr groß sind und daher viel Verarbeitungszeit in Anspruch nehmen. Die Bilder der nächsten Kamerageneration werden noch größer sein. Es empfiehlt sich, eine kleinere, niedrigere Auflösungsversion eines Bilds bereitzustellen, in der Regel im JPEG-Format, die schnell decodiert und "sofort" angezeigt werden kann, wenn ein Benutzer es anfordert. Eine Anwendung kann eine Vorschau anfordern, bevor das tatsächliche Bild decodiert werden soll, um benutzern eine bessere Benutzererfahrung zu bieten, und zeigt ihnen eine Bildschirmformatdarstellung des Bilds an, während sie darauf warten, das tatsächliche Bild zu decodieren. Codecs sollten zwar Vorschauversionen bieten, aber Codecs, die IWICBitmapSourceTransform nicht unterstützen, sollten dies auf jeden Fall tun.
Wenn Sie eine JPEG-Vorschau bereitstellen, müssen Sie keinen JPEG-Encoder schreiben, um sie zu codieren. Sie sollten an den JPEG-Encoder delegieren, der mit der WIC-Plattform zum Codieren von Vorschau- und Miniaturansichten ausgeliefert wird.
Zugehörige Themen
-
Referenz
-
Konzept
-
Implementieren von IWICBitmapCodecProgressNotification (Encoder)