使用 WIC 从流中解码图像
Decoding image from stream using WIC
我正在尝试使用 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
) 时它中断了。前一种方法完美无缺,而后一种方法会导致此函数 return HRESULT 0x88982F60 (WINCODEC_ERR_BADIMAGE)。
明确一点:图像的加载方式没有区别,除了从流而不是文件名加载图像之外。
为什么会发生这种情况,我该如何解决?我需要能够加载我只能作为流访问的图像,并且我不想将它们保存到临时文件来实现这一点。
这些是我创建的用于解码图像的方法:
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
class持有的字段,在class销毁时销毁。这可能是问题的根源。与使用文件名的重载不同:
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
对象时不会出现任何问题。
我正在尝试使用 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
) 时它中断了。前一种方法完美无缺,而后一种方法会导致此函数 return HRESULT 0x88982F60 (WINCODEC_ERR_BADIMAGE)。
明确一点:图像的加载方式没有区别,除了从流而不是文件名加载图像之外。
为什么会发生这种情况,我该如何解决?我需要能够加载我只能作为流访问的图像,并且我不想将它们保存到临时文件来实现这一点。
这些是我创建的用于解码图像的方法:
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
class持有的字段,在class销毁时销毁。这可能是问题的根源。与使用文件名的重载不同:
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
对象时不会出现任何问题。