Реализация IWICBitmapEncoder
IWICBitmapEncoder
- инициализация
- ОпределитьФорматКонтейнера
- GetEncoderInfo
- СоздатьНовуюРаму
- коммит
- УстановитьПредпросмотр
Этот интерфейс является аналогом интерфейса интерфейса 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);
};
Как обсуждалось в Implementing IWICBitmapDecoder, некоторые форматы изображений имеют глобальные эскизы, контексты цвета или метаданные, а многие форматы изображений предоставляют их только на основе кадра. Поэтому методы настройки являются необязательными для IWICBitmapEncoder, но требуются для IWICBitmapFrameEncode. Мы обсудим методы, которые являются необязательными для IWICBitmapEncoder в разделе IWICBitmapFrameEncode, где они наиболее часто реализуются.
Если глобальные эскизы не поддерживаются, верните WINCODEC_ERR_CODECNOTHUMBNAIL в методе SetThumbnail IWICBitmapEncoder. Если вы не поддерживаете палитру на уровне контейнера или если изображение, которое вы кодируете, не имеет индексированного формата, верните значение WINCODEC_ERR_PALETTEUNAVAILABLE из метода SetPalette. Для всех других методов, которые не поддерживаются, верните WINCODEC_ERR_UNSUPPORTEDOPERATION.
Инициализировать
инициализация — это первый метод, вызываемый на IWICBitmapEncoder после его создания экземпляра. Поток изображений передается кодировщику, и вызывающий объект может дополнительно указать параметр кэша. В случае декодера поток доступен только для чтения, но поток, передаваемый кодировщику, является потоком записи, в который кодировщик сериализует все данные изображения и метаданные. Параметры кэша кодировщика также отличаются.
enum WICBitmapEncoderCacheOption
{
WICBitmapEncoderCacheInMemory,
WICBitmapEncoderCacheTempFile,
WICBitmapEncoderNoCache
}
Приложение может запрашивать у кодировщика кэширование данных изображения в памяти, во временном файле или запись непосредственно в файл без кэширования. При запросе кэшировать данные во временном файле кодировщик должен создать временный файл на диске и записать непосредственно в этот файл без кэширования в памяти. Когда вызывающий объект выбирает опцию 'без кэша', каждый кадр должен быть зафиксирован в порядке перед созданием следующего кадра.
ПолучитьФорматКонтейнера
Метод 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 предоставляет небольшой набор канонических параметров кодировщика, используемых некоторыми общими форматами изображений. Все параметры канонического кодировщика являются необязательными, и кодеки не требуют поддержки любого из них. Причина, по которой они предоставляются в качестве канонических параметров, заключается в том, что многие приложения предоставляют пользовательский интерфейс пользователям, чтобы указать эти параметры при сохранении файла изображения в формате, который поддерживает их. Предоставление канонического способа указания этих параметров упрощает взаимодействие приложений с кодировщиками. Параметры канонического кодировщика перечислены в следующей таблице.
Параметр кодировщика | ТипПеременной | Диапазон значений |
---|---|---|
Без потерь | VT_BOOL | Правда/Ложь |
ImageQuality | VT_R4 | 0.0-1.0 |
КачествоСжатия | VT_R4 | 0.0-1.0 |
BitmapTransform | VT_UI1 | WICBitmapTransformOptions |
Если кодек поддерживает кодировку без потери, вы должны предоставить параметр кодировщика без потери в качестве способа для приложений запрашивать, чтобы изображение было закодировано без потери. Если вызывающий объект задает этому свойству значение True, следует игнорировать параметр ImageQuality и кодировать изображение без потерь.
Параметр ImageQuality позволяет приложению указать степень точности, с которой кодировать изображение. Этот параметр позволяет пользователю сделать компромисс между качеством изображения и скоростью и (или) размером файла. JPEG является примером формата изображения, поддерживающего этот компромисс. Значение 0.0 указывает на то, что точность имеет низкую важность, и кодировщик должен использовать свой самый устаревший алгоритм. Значение 1.0 указывает, что точность является самой важной, и кодировщик должен сохранить максимальную точность. (В зависимости от кодека это может быть синонимом параметра "Без потери". Однако если кодек поддерживает кодировку без потери, а если для параметра "Без потери" задано значение True, параметр ImageQuality должен быть проигнорирован.)
Параметр CompressionQuality позволяет приложению указать эффективность сжатия, используемого при кодировании изображения. Очень эффективный алгоритм может создать меньший файл изображения с тем же качеством, что и менее эффективный алгоритм сжатия, но может занять больше времени для кодирования. Этот параметр позволяет пользователю указать компромисс между размером файла и скоростью кодирования, сохраняя одинаковый уровень качества. TIFF является примером формата изображения, поддерживающего этот компромисс. (Обратите внимание, что формат, например JPEG, поддерживает различные уровни сжатия, но более высокий уровень сжатия приводит к снижению качества изображения. Таким образом, формат изображения JPEG будет предоставлять параметр ImageQuality вместо параметра CompressionQuality.) Значение 0.0 для этого параметра указывает на то, что изображение следует сжимать как можно быстрее, не уменьшая точность, за счет большего размера файла. Значение 1.0 указывает, что необходимо создать наименьший возможный размер файла (на том же уровне качества), независимо от того, сколько времени может потребоваться кодировать его. Кодек может поддерживать как параметр ImageQuality, так и параметр CompressionQuality, где параметр ImageQuality указывает допустимую степень потери, а параметр CompressionQuality предлагает компромисс по размеру и скорости на указанном уровне качества.
Параметр BitmapTransform позволяет вызывающей стороне указать угол поворота или ориентацию по вертикали и горизонтали при кодировании. Перечисление WICBitmapTransformOptions, используемое для указания запрошенного преобразования, совпадает с перечислением, используемым при запросе преобразования во время декодирования через интерфейс IWICBitmapSourceTransform.
Обратите внимание, что кодировщики не ограничены параметрами канонического кодировщика. Назначение параметров кодировщика заключается в том, чтобы кодировщики могли предоставлять свои возможности и не ограничивать типы возможностей, которые можно предоставить. Убедитесь, что параметры кодировщика хорошо документированы. Несмотря на то, что приложение может использовать пакет свойств, возвращаемый из этого метода, чтобы обнаружить имена, типы и диапазоны значений для параметров, которые вы поддерживаете, единственный способ узнать их смыслы или как предоставить их в пользовательском интерфейсе, содержится в документации.
Зафиксировать
Коммит — это метод, который вызывается после сериализации всех данных изображения и метаданных в поток. Этот метод следует использовать для сериализации данных изображения предварительного просмотра в поток вместе с любыми глобальными эскизами, метаданными, палитрой или другими элементами, если это пригодно. Этот метод не должен закрывать файловый поток, так как приложение, открывающее поток, должно закрыть его.
В разделе метода IWICBitmapFrameEncode:Commit содержатся сведения о том, как IWICBitmapEncoderCacheOptions влияет на поведение этого метода.
УстановитьПредпросмотр
SetPreview используется для создания предварительного просмотра образа. Хотя это не является строгим требованием, чтобы у каждого изображения был предварительный просмотр, это крайне рекомендуется. Современные цифровые камеры и сканеры создают очень высокие изображения разрешения, которые, как правило, очень большие и, следовательно, занимают значительное время обработки для декодирования. Изображения из следующего поколения камер будут еще больше. Рекомендуется предоставить меньшую, более низкую версию изображения, как правило, в формате JPEG, которая может быть быстро декодирована и отображаться "мгновенно" при запросе пользователя. Приложение может запросить предварительную версию перед запросом на декодирование фактического изображения, чтобы обеспечить лучший интерфейс для пользователей, и показать им представление размера экрана изображения во время ожидания декодирования фактического изображения. Хотя кодеки должны предоставлять предварительные версии, кодеки, которые не поддерживают IWICBitmapSourceTransform, определенно должны сделать это.
Если вы предоставляете предварительную версию JPEG, вам не нужно писать кодировщик JPEG для его кодирования. Вам следует делегировать кодировку JPEG кодировщику, который поставляется с платформой WIC, для кодирования как предварительных изображений, так и эскизов.
Связанные разделы
-
Справочник
-
концептуальные