使用WIC从流中解码图像

时间:2018-02-26 06:38:55

标签: c# windows direct2d 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)时,它就会中断。前一种方法完美无缺,而后一种方法使该函数返回HRESULT 0x88982F60(WINCODEC_ERR_BADIMAGE)。

要明确:除了从流而不是文件名加载图像之外,图像的加载方式没有区别

为什么会发生这种情况,我该如何解决?我需要能够加载我只能作为流访问的图像,并且我不想将它们保存到临时文件中来实现它。

1 个答案:

答案 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);
}

internalWICStreamBitmapDecoder类所持有的字段,它在处理类时被处理。这可能是问题的根源。与使用文件名的重载不同:

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对象时,不会出现任何问题。