Какой фильтр для кодирования PNG чересстрочной с использованием компонентов обработки изображений Windows (WIC) с оболочкой C#?
Я пытаюсь закодировать изображение как чересстрочный PNG с помощью WIC. Я могу без проблем сохранить изображение в формате png и установить режим чересстрочной развертки. Но если я пытаюсь установить режим фильтра (любой фильтр), я получаю следующую ошибку:
[System.Runtime.InteropServices.COMException] = {"The bitmap property type is unexpected. (Exception from HRESULT: 0x88982F8E)"}
Я неправильно устанавливаю значение свойства bag? Это код, исключение выдается в propBag.Write.
[...]
var arg = new IPropertyBag2[1];
encoder.CreateNewFrame(out outputFrame, arg);
var propBag = arg[0];
var propertyBagOptions = new PROPBAG2[2];
propertyBagOptions[0].pstrName = "InterlaceOption";
propertyBagOptions[1].pstrName = "FilterOption";
propBag.Write(2, propertyBagOption1, new object[] { true, WICPngFilterOption.WICPngFilterAdaptive});
[...]
Спасибо за помощь, Стефани
1 ответ
Я считаю, что это потому, что FilterOption
свойство должно быть байтом без знака:
| Property Name |VARTYPE|Value Range | Default Value |
|---------------|-------|------------------|------------------------|
|InterlaceOption|VT_BOOL|TRUE/FALSE |FALSE |
|FilterOption |VT_UI1 |WICPngFilterOption|WICPngFilterUnspecified |
Основной Write
Метод отмечен, чтобы маршал Value
как VARIANT
(т.е. UnmanagedType.Struct
), что правильно:
void Write(
uint cProperties,
[MarshalAs(UnmanagedType.LPArray)] PROPBAG2[] pPropBag,
[MarshalAs(UnmanagedType.Struct)] ref object pvarValue
);
Я не собираюсь проверять это; потому что я не могу, но я думаю, что исправление заключается в приведении вашей опции фильтра PNG к эквиваленту C# байта без знака.
propBag.Write(
1,
propertyBagOption,
UInt8(WICPngFilterOption.WICPngFilterAdaptive));
Причина, по которой я думаю, что это потому, что из моего собственного кода, я дал значение свойства как вариант. Но вариант был на самом деле подписанным 32-разрядным (иначе Int32
). Это вызвало ошибку:
0x88982F8E
Когда вы смотрите на WinCodec.h
(это собственный код, который использует.NET-образы), он соответствует ошибке:
WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE = HRESULT($88982f8E);
Я должен убедиться, что вариант содержит VT_UI1:
propertyBagHelper.Write('FilterOption', VarAsType(WICPngFilterAdaptive, VT_UI1));
Тогда это удалось.
Это все замечательно из нативного кода, когда вы знаете, что происходит. Мир оболочки.NET/CLR/C# любит запутывать все; так что вы не знаете, что содержат параметры, когда передаете их.
Примечание. Любой код, опубликованный в открытом доступе. Атрибуция не требуется.