Я пытаюсь кодировать изображение как чересстрочный png, используя WIC. Я могу сохранить изображение как png без проблем и установить режим чересстрочной развертки. Но если я попытаюсь установить filtermode (любой фильтр), я получаю следующую ошибку:
[System.Runtime.InteropServices.COMException] = {"The bitmap property type is unexpected. (Exception from HRESULT: 0x88982F8E)"}
Я устанавливаю значение мешка собственности неправильно? Это код, исключение выбрано в 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});
[...]
Спасибо за помощь, Стефани
Я считаю, что это связано с тем, что свойство 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 на эквивалент С# байта без знака.
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/С# любит обмазывать все; поэтому вы не знаете, какие параметры содержатся при их передаче.
Примечание. Любой код, выпущенный в общедоступный домен. Никакой атрибуции не требуется.