我正在尝试使用WIC在C#中加载图像,使用SharpDX作为包装器(这是用.NET编写的Direct2D应用程序)。我可以通过创建BitmapDecoder
来完美地加载我的图像:
C#代码:
new BitmapDecoder(Factory, fileName, NativeFileAccess.Read, DecodeOptions.CacheOnLoad)
C ++等效:
hr = m_pIWICFactory->CreateDecoderFromFilename(
fileName,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pIDecoder);
顺便说一下,fileName
包含JPEG图像的路径。现在,这非常有效,但如果我尝试使用流加载图像,则会崩溃:
C#代码:
new BitmapDecoder(Factory, stream, DecodeOptions.CacheOnLoad)
C ++等效:
hr = m_pIWICFactory->CreateDecoderFromStream(
pIWICStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pIDecoder);
这与JPEG文件中的数据完全相同,并且大部分工作方式与之前的方式相同。但是当我致电SharpDX.Direct2D1.Bitmap.FromWicBitmap()
(ID2D1RenderTarget::CreateBitmapFromWicBitmap
)时,它就会中断。前一种方法完美无缺,而后一种方法使该函数返回HRESULT 0x88982F60(WINCODEC_ERR_BADIMAGE)。
要明确:除了从流而不是文件名加载图像之外,图像的加载方式没有区别。
为什么会发生这种情况,我该如何解决?我需要能够加载我只能作为流访问的图像,并且我不想将它们保存到临时文件中来实现它。
答案 0 :(得分:0)
这些是我为解码图像而创建的方法:
internal void Load(Stream stream)
{
using(var decoder = new BitmapDecoder(Factory, stream, DecodeOptions.CacheOnLoad))
Decode(decoder);
}
internal void Load(string fn)
{
using (var decoder =
new BitmapDecoder(Factory, fn, NativeFileAccess.Read, DecodeOptions.CacheOnLoad))
Decode(decoder);
}
显然,如果使用了流,则在您仍在阅读图像时无法处理解码器。去搞清楚。无论如何,这最终起作用了:
internal void Load(Stream stream)
{
var decoder = new BitmapDecoder(Factory, stream, DecodeOptions.CacheOnLoad);
Decode(decoder);
}
internal void Load(string fn)
{
using (var decoder =
new BitmapDecoder(Factory, fn, NativeFileAccess.Read, DecodeOptions.CacheOnLoad))
Decode(decoder);
}
但现在我不得不担心以后处理解码器。
<强>更新强>
这种奇怪的行为差异是由SharpDX的实施细节引起的:
public BitmapDecoder(ImagingFactory factory, Stream streamRef, SharpDX.WIC.DecodeOptions metadataOptions)
{
internalWICStream = new WICStream(factory, streamRef);
factory.CreateDecoderFromStream(internalWICStream, null, metadataOptions, this);
}
internalWICStream
是BitmapDecoder
类所持有的字段,它在处理类时被处理。这可能是问题的根源。与使用文件名的重载不同:
public BitmapDecoder(ImagingFactory factory, string filename, System.Guid? guidVendorRef, NativeFileAccess desiredAccess, SharpDX.WIC.DecodeOptions metadataOptions)
{
factory.CreateDecoderFromFilename(filename, guidVendorRef, (int)desiredAccess, metadataOptions, this);
}
未设置 internalWICStream
,因为该流由Windows管理。因此,当托管BitmapDecoder
对象时,不会出现任何问题。