Поделиться через


Внедрение IWICBitmapFrameEncode

IWICBitmapFrameEncode

IWICBitmapFrameEncode является аналогом кодировщика в интерфейсе IWICBitmapFrameDecode. Этот интерфейс можно реализовать в классе кодирования на уровне кадра, который является классом, который выполняет фактическое кодирование битов изображения для каждого кадра.

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 );
};

Инициализировать

инициализация является первым метод ом, который вызывается в объекте IWICBitmapFrameEn code после создания экземпляра. Этот метод имеет один параметр, который может иметь значение NULL. Этот параметр представляет параметры кодировщика и тот же экземпляр IPropertyBag2, созданный в методе CreateNewFrame декодирования на уровне контейнера, и передается вызывающей стороне в параметре pIEncoderOptions этого метода. В то время вы заполняли структуру IPropertyBag2 свойствами, которые представляют параметры кодирования, поддерживаемые кодировщиком уровня кадра. Вызывающая сторона теперь предоставляет значения для этих свойств, чтобы указать определенные параметры кодирования, и передает этот же объект обратно вам для инициализации объекта IWICBitmapFrameEncode. При кодировании битов изображения следует применять указанные параметры.

SetSize и SetResolution

SetSize и SetResolution понятны сами по себе. Вызывающий объект использует эти методы для указания размера и разрешения для закодированного изображения.

SetPixelFormat

SetPixelFormat используется для запроса формата пикселей, в котором кодируется изображение. Если запрошенный формат пикселей не поддерживается, необходимо вернуть GUID ближайшего формата пикселей, который поддерживается в pPixelFormat, который является параметром in/out.

SetColorContexts

SetColorContexts используется для указания одного или нескольких допустимых контекстов цвета (также известных как профили цветов) для этого изображения. Важно указать контексты цвета, поэтому приложение, которое декодирует изображение позже, может преобразоваться из исходного профиля цвета в целевой профиль устройства, используемого для отображения или печати изображения. Без профиля цвета невозможно получить согласованные цвета на разных устройствах. Это может быть разочаровывающим для конечных пользователей, когда их фотографии выглядят по-разному на разных мониторах, и они не могут сделать так, чтобы отпечатки соответствовали тому, что они видят на экране.

GetMetadataQueryWriter

GetMetadataQueryWriter возвращает IWICMetadataQueryWriter, которую приложение может использовать для вставки или изменения определенных свойств метаданных в блоке метаданных в кадре изображения.

Вы можете создать экземпляр IWICMetadataQueryWriter из IWICComponentFactory несколькими способами. Вы можете создать его из IWICMetadataBlockWriter, так же, как IWICMetadataQueryReader был создан из IWICMetadataBlockReader в методе GetMetadataQueryReader интерфейса IWICBitmapFrameDecode.

IWICMetadataQueryWriter* piMetadataQueryWriter = NULL;
HRESULT hr;

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

Вы также можете создать его из существующего IWICMetadataQueryReader, например полученного с помощью предыдущего метода.

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

Параметр pguidVendor позволяет указать конкретного поставщика, которого автор запросов будет использовать при создании экземпляра функции записи метаданных. Например, если вы предоставляете собственные записи метаданных, может потребоваться указать собственный GUID поставщика. Вы можете передать NULL этому параметру, если у вас нет предпочтений.

SetThumbnail

SetThumbnail используется для предоставления эскиза. Все изображения должны предоставлять эскиз либо глобально, на каждом фрейме, или и то, и другое. Методы GetThumbnail и SetThumbnail являются необязательными на уровне контейнера, но если кодек возвращает WINCODEC_ERR_CODECNOTHUMBNAIL из метода GetThumbnail, то компонент обработки изображений Windows (WIC) вызовет метод GetThumbnail для кадра 0. Если миниатюра не найдена ни в одном из мест, WIC должен декодировать полное изображение и масштабировать его до размера миниатюры, что может привести к большой потере производительности для больших изображений.

Эскиз должен иметь такой размер и разрешение, что позволяет его быстро декодировать и отображать. По этой причине эскизы чаще всего представляют собой изображения JPEG. Обратите внимание, что если вы используете JPEG для эскизов, вам не нужно писать кодировщик JPEG для их кодирования или декодировщик JPEG для их декодирования. Вы всегда должны использовать кодек JPEG, который поставляется с платформой WIC, для кодирования и декодирования миниатюр.

WritePixels

WritePixels — это метод, используемый для передачи строк сканирования из растрового изображения в памяти для кодирования. Метод будет вызываться многократно, пока не будут переданы все строки сканирования. Параметр lineCount указывает, сколько строк сканирования необходимо записать в этом вызове. Параметр cbStride указывает количество байтов на строку сканирования. cbBufferSize указывает размер буфера, передаваемого в параметре pbPixels, который содержит фактические биты изображения, которые необходимо закодировать. Если объединенная высота строк сканирования от накопительных вызовов превышает высоту, указанную в методе SetSize, возвращается WINCODEC_ERR_TOOMANYSCANLINES.

Если WICBitmapEncoderCacheOptionWICBitmapEncoderCacheInMemory, строки сканирования должны кэшироваться в памяти, пока не будут переданы все строки сканирования. Если параметр кэша кодировщика WICBitmapEncoderCacheTempFile, строки сканирования должны кэшироваться во временном файле, созданном при инициализации объекта. В любом из этих случаев изображение не должно быть закодировано до тех пор, пока вызывающий объект не вызывает Commit. В случае, когда параметр кэша WICBitmapEncoderNoCache, кодировщик должен закодировать строки сканирования по мере их получения, если это возможно. (В некоторых форматах это невозможно, и строки сканирования должны быть кэшированы до вызова выполнения Commit.)

Большинство необработанных кодеков не реализуют WritePixels, так как они не поддерживают изменение битов изображения в необработанном файле. Необработанные кодеки по-прежнему должны реализовывать WritePixels, так как при добавлении метаданных он может увеличить размер файла, требуя перезаписи файла на диске. В этом случае необходимо иметь возможность копировать существующие биты изображений, то есть то, что делает метод WritePixels.

WriteSource

WriteSource используется для кодирования объекта IWICBitmapSource. Первый параметр — это указатель на объект IWICBitmapSource. Второй параметр — это WICRect, указывающий интересующий регион для кодирования. Этот метод может вызываться несколько раз в последовательности, если ширина каждого прямоугольника совпадает с шириной закодированного окончательного изображения. Если ширина прямоугольника, передаваемого в параметре prc, отличается от ширины, указанной в методе SetSize, возвращается WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS. Если объединенная высота строк сканирования, полученная в результате последовательных вызовов, превышает высоту, указанную в методе SetSize, верните WINCODEC_ERR_TOOMANYSCANLINES.

Параметры кэша работают так же, как и с помощью метода WritePixels, описанного ранее.

Совершать

Commit — это метод, который сериализует биты закодированного изображения в поток файлов и циклически обходит всех пишущих метаданные объектов для кадра, запрашивающих сериализацию их метаданных в поток. В случае, если параметр кэша кодировщика имеет значение WICBitmapEncoderCacheInMemory или WICBitmapEncoderCacheTempFile, этот метод также отвечает за кодировку изображения, а при использовании параметра кэша — WICBitmapEncoderCacheTempFile, метод Commit также должен удалить временный файл, используемый для кэширования данных изображения перед кодировкой.

Этот метод всегда вызывается после того, как все строки сканирования или прямоугольники, составляющие изображение, обработаны с использованием либо метода Commit, либо метода WriteSource. Размер окончательного прямоугольника, составленного из накопленных вызовов WritePixels или WriteSource, должен совпадать с размером, указанным в методе SetSize. Если размер не соответствует ожидаемому размеру, этот метод должен вернуть WINCODECERROR_UNEXPECTEDSIZE.

Чтобы пройти по всем записывающим метаданные и указать каждому из них сериализовать свои метаданные в поток, вызывайте GetWriterByIndex для итерации по записывающим для каждого блока, а затем вызывайте IWICPersistStream.Save для каждого из записывающих метаданные.

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. Если изображение использует индексированный формат, используйте этот метод, чтобы указать палитру цветов, используемых в изображении. Если ваш кодек не имеет индексированного формата, этот метод должен вернуть WINCODEC_ERR_PALETTEUNAVAILABLE.

концептуальные

Реализация IWICBitmapCodecProgressNotification (Кодировщик)

Реализация IWICMetadataBlockWriter

Как написать WIC-Enabled CODEC

Обзор имиджевой системы Windows