1

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

感谢您的帮助,斯蒂芬妮

4

1 回答 1

0

我相信这是因为FilterOption属性需要是 Unsigned Byte

| Property Name |VARTYPE|Value Range       | Default Value          | 
|---------------|-------|------------------|------------------------|
|InterlaceOption|VT_BOOL|TRUE/FALSE        |FALSE                   |
|FilterOption   |VT_UI1 |WICPngFilterOption|WICPngFilterUnspecified |

底层Write方法被标记为编组ValueVARIANT(即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# 包装器世界喜欢混淆一切;所以你在传递参数时并不真正知道参数包含什么。

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

于 2014-06-14T01:33:32.770 回答