какой фильтр для кодирования чересстрочной развертки png с использованием компонентов обработки изображений Windows (wic) с оболочкой С#?

Я пытаюсь закодировать изображение как чересстрочный png с помощью WIC. Я могу без проблем сохранить изображение в формате png и установить чересстрочный режим. Но если я пытаюсь установить режим фильтра (любой фильтр), я получаю следующую ошибку:

[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});
[...]

Спасибо за помощь, Стефани


person Stephanie    schedule 28.05.2014    source источник


Ответы (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#, эквивалентный байту unsigned byte.

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

Примечание. Любой код, опубликованный в открытом доступе. Атрибуция не требуется.

person Ian Boyd    schedule 14.06.2014