Реализация IWICBitmapEncoder

IWICBitmapEncoder

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

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

Как описано в разделе Реализация IWICBitmapDecoder, некоторые форматы изображений имеют глобальные эскизы, контексты цвета или метаданные, в то время как многие форматы изображений предоставляют их только для каждого кадра. Таким образом, методы для их установки являются необязательными в IWICBitmapEncoder, но являются обязательными в IWICBitmapFrameEncode. Мы обсудим необязательные методы в IWICBitmapEncoder в разделе IWICBitmapFrameEncode, где они наиболее часто реализуются.

Если вы не поддерживаете глобальные эскизы, верните WINCODEC_ERR_CODECNOTHUMBNAIL из метода SetThumbnail в IWICBitmapEncoder. Если вы не поддерживаете палитру уровня контейнера или кодируемое изображение не имеет индексированного формата, верните WINCODEC_ERR_PALETTEUNAVAILABLE из метода SetPalette. Для других неподдерживаемых методов верните WINCODEC_ERR_UNSUPPORTEDOPERATION.

Initialize

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

enum WICBitmapEncoderCacheOption
{
   WICBitmapEncoderCacheInMemory,
   WICBitmapEncoderCacheTempFile,
   WICBitmapEncoderNoCache
}

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

GetContainerFormat

GetContainerFormat реализуется так же, как и метод GetContainerFormat в разделе Реализация IWICBitmapDecoder.

GetEncoderInfo

GetEncoderInfo возвращает объект IWICBitmapEncoderInfo . Чтобы получить объект IWICBitmapEncoderInfo , просто передайте GUID кодировщика в метод CreateComponentInfo в IWICImagingFactory, а затем запросите интерфейс IWICBitmapEncoderInfo .

См. пример в разделе Реализация IWICBitmapDecoder в разделе GetDecoderInfo.

CreateNewFrame

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

Одним из преимуществ компонента обработки образов Windows (WIC) является то, что он предоставляет уровень абстракции для приложений, который позволяет им работать со всеми форматами изображений одинаково. Однако не все форматы изображений полностью совпадают. Некоторые форматы изображений имеют возможности, которых нет у других. Чтобы приложения могли воспользоваться этими уникальными возможностями, необходимо предоставить кодеку способ их предоставления. Это предназначение параметров кодировщика. Если кодек поддерживает любые параметры кодировщика, необходимо создать объект IPropertyBag2 , который предоставляет поддерживаемые параметры кодировщика, и вернуть его в параметре ppIEncoderOptions этого метода. Затем вызывающий объект может использовать этот объект IPropertyBag2, чтобы определить, какие параметры кодировщика поддерживает кодек. Если вызывающий объект хочет указать значения для любого из поддерживаемых параметров кодировщика, он присвоит значение соответствующему свойству в объекте IPropertyBag2 и передаст его только что созданному объекту IWICBitmapFrameEncode в методе Initialize.

Чтобы создать экземпляр объекта IPropertyBag2 , сначала необходимо создать структуру PROPBAG2, чтобы указать каждый параметр кодировщика, поддерживаемый кодировщиком, и его тип данных для каждого свойства. Затем необходимо реализовать объект IPropertyBag2, который применяет диапазоны значений для каждого свойства при записи и согласовывает все конфликтующие или перекрывающиеся значения. Для простых наборов неконфликтных параметров кодировщика можно вызвать метод CreateEncoderPropertyBag , который создаст простой объект IPropertyBag2 с помощью свойств, указанных в структуре PROPBAG2. По-прежнему необходимо принудительно применять диапазоны значений. Для более сложных параметров кодировщика или при необходимости согласования конфликтующих значений следует написать собственную реализацию IPropertyBag2.

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

Параметр кодировщика VARTYPE Диапазон значений:
Lossless VT_BOOL. Истина/ложь
ImageQuality VT_R4 0.0-1.0
CompressionQuality VT_R4 0.0-1.0
BitmapTransform VT_UI1 WICBitmapTransformOptions

 

Если кодек поддерживает кодировку без потерь, следует предоставить параметр кодировщика Lossless в качестве способа для приложений запросить без потерь кодирование изображения. Если вызывающий объект задает этому свойству значение True, следует игнорировать параметр ImageQuality и кодировать изображение без потери.

Параметр ImageQuality позволяет приложению указать степень точности для кодирования изображения. Этот параметр позволяет пользователю сойтить качество изображения от скорости и (или) размера файла. JPEG — это пример формата изображения, который поддерживает этот компромисс. Значение 0,0 указывает, что точность имеет низкую важность, и кодировщик должен использовать свой алгоритм с наибольшей потерей. Значение 1,0 указывает на то, что точность является наиболее важной, и кодировщик должен сохранять максимально возможную точность. (В зависимости от кодека это может быть синонимом параметра Без потерь. Однако если кодек поддерживает кодировку без потерь и если для параметра Lossless задано значение True, параметр ImageQuality следует игнорировать.)

Параметр CompressionQuality позволяет приложению указать эффективность сжатия, используемую при кодировании изображения. Очень эффективный алгоритм может создать файл изображения меньшего размера с тем же качеством, что и менее эффективный алгоритм сжатия, но может занять больше времени для кодирования. Этот параметр позволяет пользователю указать компромисс между размером файла и скоростью кодирования, сохраняя при этом тот же уровень качества. TIFF — это пример формата изображения, который поддерживает этот компромисс. (Обратите внимание, что такой формат, как JPEG, поддерживает различные уровни сжатия, но более высокий уровень сжатия приводит к снижению качества изображения. Таким образом, формат изображения JPEG будет предоставлять параметр ImageQuality, а не CompressionQuality.) Значение 0,0 для этого параметра указывает, что следует сжимать изображение как можно быстрее, не снижая точность, за счет большего размера файла. Значение 1.0 указывает, что следует создать файл наименьшего размера (с одинаковым уровнем качества), независимо от того, сколько времени может потребоваться для его кодирования. Кодек может поддерживать параметры ImageQuality и CompressionQuality, где параметр ImageQuality указывает приемлемую степень потери, а параметр CompressionQuality предлагает компромисс размера и скорости на указанном уровне качества.

Параметр BitmapTransform позволяет вызывающей стороне указать угол поворота, вертикальную или горизонтальную ориентацию поворота при кодировании. Перечисление WICBitmapTransformOptions, используемое для указания запрошенного преобразования, является тем же перечислением, которое используется при запросе преобразования во время декодирования через интерфейс IWICBitmapSourceTransform.

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

Commit

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

В разделе о методе IWICBitmapFrameEncode:Commit содержатся сведения о том, как IWICBitmapEncoderCacheOptions влияет на поведение этого метода.

SetPreview

SetPreview используется для создания предварительного просмотра образа. Хотя это не обязательно, чтобы у каждого изображения был предварительный просмотр, настоятельно рекомендуется. Современные цифровые камеры и сканеры создают изображения с очень высоким разрешением, которые, как правило, очень большие и, следовательно, занимают значительное время обработки для декодирования. Изображения с камер следующего поколения будут еще больше. Рекомендуется предоставить уменьшенную версию изображения с низким разрешением, обычно в формате JPEG, которая может быть быстро декодирована и отображена "мгновенно", когда пользователь запрашивает его. Приложение может запросить предварительный просмотр перед запросом декодирования фактического изображения, чтобы обеспечить лучшее взаимодействие с пользователями, и показать им представление изображения в размере экрана, пока они ожидают декодирования фактического изображения. Хотя кодеки должны предоставлять предварительные версии, кодеки, которые не поддерживают IWICBitmapSourceTransform , обязательно должны сделать это.

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

Reference

IWICBitmapEncoder

IWICBitmapFrameEncode

Основные понятия

Интерфейсы кодировщика

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

Создание кодека WIC-Enabled

Общие сведения о компоненте обработки образов Windows