哪个过滤器用于使用c#包装器使用windows成像组件(wic)对png进行编码?

时间:2014-05-28 08:28:04

标签: c# wic

我尝试使用WIC将图像编码为隔行扫描png。我可以将图像保存为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});
[...]

感谢您的帮助, 斯蒂芬妮

1 个答案:

答案 0 :(得分:0)

我相信这是因为FilterOption property needs to be an Unsigned Byte

| 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#包装器世界喜欢混淆一切;所以当你传递参数时,你真的不知道参数包含的内容。

  

注意:任何已发布到公共领域的代码。无需归属。