我尝试使用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});
[...]
感谢您的帮助, 斯蒂芬妮
答案 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#包装器世界喜欢混淆一切;所以当你传递参数时,你真的不知道参数包含的内容。
注意:任何已发布到公共领域的代码。无需归属。