Implementieren von IWICBitmapFrameEncode

IWICBitmapFrameEncode

IWICBitmapFrameEncode ist das Pendant des Encoders zur IWICBitmapFrameDecode-Schnittstelle . Sie können diese Schnittstelle in Ihrer Codierungsklasse auf Frameebene implementieren. Dies ist die Klasse, die die tatsächliche Codierung der Bildbits für jeden Frame durchführt.

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

// Optional method
   HRESULT SetPalette ( IWICPalette *pIPalette );
};

Initialize

Initialize ist die erste Methode, die für ein IWICBitmapFrameEncode-Objekt aufgerufen wird, nachdem es instanziiert wurde. Diese Methode verfügt über einen Parameter, der auf NULL festgelegt werden kann. Dieser Parameter stellt die Encoderoptionen dar und entspricht dem IPropertyBag2-instance, den Sie in der CreateNewFrame-Methode für den Decoder auf Containerebene erstellt und im pIEncoderOptions-Parameter dieser Methode an den Aufrufer zurückgegeben haben. Zu diesem Zeitpunkt haben Sie die IPropertyBag2-Struktur mit Eigenschaften aufgefüllt, die die vom Encoder auf Frameebene unterstützten Codierungsoptionen darstellen. Der Aufrufer hat nun Werte für diese Eigenschaften bereitgestellt, um bestimmte Codierungsoptionsparameter anzugeben, und gibt dasselbe Objekt an Sie zurück, um das IWICBitmapFrameEncode-Objekt zu initialisieren. Sie sollten die angegebenen Optionen beim Codieren der Bildbits anwenden.

SetSize und SetResolution

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

SetPixelFormat

SetPixelFormat wird verwendet, um ein Pixelformat anzufordern, in dem das Bild codiert werden soll. Wenn das angeforderte Pixelformat nicht unterstützt wird, sollten Sie die GUID des nächstgelegenen Pixelformats zurückgeben, das in pPixelFormat unterstützt wird, bei dem es sich um einen in/out-Parameter handelt.

SetColorContexts

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, damit eine Anwendung, die das Bild zu einem späteren Zeitpunkt decodiert, vom Quellfarbprofil in das Zielprofil des Geräts konvertieren kann, das zum Anzeigen oder Drucken des Bilds verwendet wird. Ohne Farbprofil ist es nicht möglich, konsistente Farben auf verschiedenen Geräten zu erhalten. Dies kann für Endbenutzer frustrierend sein, wenn ihre Fotos auf verschiedenen Monitoren unterschiedlich aussehen und sie die Drucke nicht so abrufen können, dass sie dem auf dem Bildschirm angezeigt werden.

GetMetadataQueryWriter

GetMetadataQueryWriter gibt einen IWICMetadataQueryWriter zurück, mit dem eine Anwendung bestimmte Metadateneigenschaften in einen Metadatenblock im Bildrahmen einfügen oder bearbeiten kann.

Sie können einen IWICMetadataQueryWriter aus der IWICComponentFactory auf verschiedene Arten instanziieren. Sie können ihn entweder aus Ihrem IWICMetadataBlockWriter erstellen, genauso wie IWICMetadataQueryReader aus einem IWICMetadataBlockReader in der GetMetadataQueryReader-Methode auf der IWICBitmapFrameDecode-Schnittstelle erstellt wurde.

IWICMetadataQueryWriter* piMetadataQueryWriter = NULL;
HRESULT hr;

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

Sie können ihn auch aus einem vorhandenen IWICMetadataQueryReader erstellen, z. B. aus dem mit der vorherigen Methode abgerufenen.

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

Mit dem Parameter pguidVendor können Sie einen bestimmten Anbieter für den Abfragewriter angeben, der beim Instanziieren eines Metadaten-Writers verwendet werden soll. Wenn Sie beispielsweise Eigene Metadaten-Writer bereitstellen, können Sie Ihre eigene Anbieter-GUID angeben. Sie können NULL an diesen Parameter übergeben, wenn Sie keine Einstellung haben.

SetThumbnail

SetThumbnail wird verwendet, um eine Miniaturansicht bereitzustellen. Alle Bilder sollten eine Miniaturansicht bereitstellen, entweder global, auf jedem Frame oder beides. Die Methoden GetThumbnail und SetThumbnail sind auf Containerebene optional, aber wenn ein Codec WINCODEC_ERR_CODECNOTHUMBNAIL aus der GetThumbnail-Methode zurückgibt, ruft Windows Imaging Component (WIC) die GetThumbnail-Methode für Frame 0 auf. Wenn an beiden Stellen keine Miniaturansicht gefunden wird, muss WIC das vollständige Bild decodieren und es auf die Miniaturbildgröße skalieren, was bei größeren Bildern zu einer hohen Leistungseinbuße führen kann.

Die Miniaturansicht sollte eine Größe und Auflösung aufweisen, mit der sie schnell decodiert und angezeigt werden kann. Aus diesem Grund sind Miniaturansichten am häufigsten JPEG-Bilder. Beachten Sie, dass Sie, wenn Sie JPEG für Ihre Miniaturansichten verwenden, keinen JPEG-Encoder schreiben müssen, um sie zu codieren, oder einen JPEG-Decoder, um sie zu decodieren. Sie sollten immer an den JPEG-Codec delegieren, der mit der WIC-Plattform zum Codieren und Decodieren von Miniaturansichten enthalten ist.

Writepixels

WritePixels ist die Methode, mit der Scanzeilen aus einer Bitmap im Arbeitsspeicher für die Codierung übergeben 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 cbStride-Parameter gibt die Anzahl der Bytes pro Scanzeile an. cbBufferSize gibt die Größe des Puffers an, der im pbPixels-Parameter übergeben wird, der die tatsächlich zu codierenden Bildbits enthält. Wenn die kombinierte Höhe der Scanzeilen aus kumulativen Aufrufen größer als die in der SetSize-Methode angegebene Höhe ist, geben Sie WINCODEC_ERR_TOOMANYSCANLINES zurück.

Wenn WICBitmapEncoderCacheOptionWICBitmapEncoderCacheInMemory ist, sollten die Scanzeilen im Arbeitsspeicher zwischengespeichert werden, bis alle Scanzeilen übergeben wurden. Wenn die Encodercacheoption WICBitmapEncoderCacheTempFile lautet, sollten die Scanzeilen in einer temporären Datei zwischengespeichert werden, die beim Initialisieren des Objekts erstellt wurde. In beiden Fällen sollte das Image erst codiert werden, wenn der Aufrufer Commit aufruft. Wenn die Cacheoption WICBitmapEncoderNoCache lautet, sollte der Encoder die Scanzeilen nach Möglichkeit codieren, sobald sie empfangen werden. (In einigen Formaten ist dies nicht möglich, und die Scanzeilen müssen zwischengespeichert werden, bis Commit aufgerufen wird.)

Die meisten unformatierten Codecs implementieren WritePixels nicht, da sie das Ändern der Bildbits in der Rohdatei nicht unterstützen. Unformatierte Codecs sollten jedoch weiterhin WritePixels implementieren, da beim Hinzufügen von Metadaten die Größe der Datei erhöht werden kann, sodass die Datei auf dem Datenträger umgeschrieben werden muss. In diesem Fall ist es erforderlich, die vorhandenen Bildbits kopieren zu können, was die WritePixels-Methode tut.

WriteSource

WriteSource wird zum Codieren eines IWICBitmapSource-Objekts verwendet. Der erste Parameter ist ein Zeiger auf ein IWICBitmapSource-Objekt . Der zweite Parameter ist ein WICRect, der den zu codierenden Bereich angibt. Diese Methode kann mehrmals hintereinander aufgerufen werden, solange die Breite jedes Rechtecks die gleiche Breite des zu codierenden endgültigen Bilds hat. Wenn sich die Breite des im prc-Parameter übergebenen Rechtecks von der in der SetSize-Methode angegebenen Breite unterscheidet, geben Sie WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS zurück. Wenn die kombinierte Höhe der Scanzeilen aus kumulativen Aufrufen größer als die in der SetSize-Methode angegebene Höhe ist, geben Sie WINCODEC_ERR_TOOMANYSCANLINES zurück.

Die Cacheoptionen funktionieren mit dieser Methode genauso wie mit der zuvor beschriebenen WritePixels-Methode .

Commit

Commit ist die Methode, die die codierten Bildbits in den Dateidatenstrom serialisiert und alle Metadatenschreiber für den Frame durchläuft, der sie anfordert, ihre Metadaten in den Stream zu serialisieren. Wenn die Encodercacheoption WICBitmapEncoderCacheInMemory oder WICBitmapEncoderCacheTempFile ist, ist diese Methode auch für die Codierung des Bilds verantwortlich, und wenn die Cacheoption WICBitmapEncoderCacheTempFile lautet, sollte die Commit-Methode auch die temporäre Datei löschen, die zum Zwischenspeichern der Bilddaten vor der Codierung verwendet wird.

Diese Methode wird immer aufgerufen, nachdem alle Scanzeilen oder Rechtecke, aus denen das Bild besteht, entweder mit der Commit - oder writeSource-Methode übergeben wurden. Die Größe des endgültigen Rechtecks, das durch die akkumulierten Aufrufe von WritePixels oder WriteSource zusammengesetzt wird, muss dieselbe Größe aufweisen, die in der SetSize-Methode angegeben wurde. Wenn die Größe nicht mit der erwarteten Größe übereinstimmt, sollte diese Methode WINCODECERROR_UNEXPECTEDSIZE zurückgeben.

Rufen Sie GetWriterByIndex auf, um die Metadatenautoren zu durchlaufen und jeden Metadaten-Writer zu serialisieren, rufen Sie getWriterByIndex auf, um die Writer für jeden Block zu durchlaufen, und rufen Sie IWICPersistStream.Save für jeden Metadatenwriter 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

Nur Codecs mit indizierten Formaten müssen die SetPalette-Methode implementieren. Wenn ein Bild ein indiziertes Format verwendet, verwenden Sie diese Methode, um die farbpalette anzugeben, die im Bild verwendet wird. Wenn Ihr Codec kein indiziertes Format aufweist, geben Sie WINCODEC_ERR_PALETTEUNAVAILABLE von dieser Methode zurück.

Konzept

Implementieren von IWICBitmapCodecProgressNotification (Encoder)

Implementieren von IWICMetadataBlockWriter

Schreiben eines WIC-Enabled CODEC

Übersicht über die Windows-Imageerstellungskomponente