【问题标题】:Decoding image from stream using WIC使用 WIC 从流中解码图像
【发布时间】:2018-08-05 13:40:28
【问题描述】:

我正在尝试使用 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)。

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

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

【问题讨论】:

  • 旁注:有区别 - 与您使用 CacheOnLoad 加载的文件和使用 CacheOnDemand 的流加载。
  • @Evk 这是一个错误,它们在我的代码中是一样的。

标签: c# windows direct2d wic


【解决方案1】:

这些是我创建的用于解码图像的方法:

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

【讨论】:

    猜你喜欢
    • 2021-01-25
    • 2021-10-26
    • 1970-01-01
    • 2013-07-10
    • 2014-09-18
    • 1970-01-01
    • 2020-11-29
    • 2021-12-23
    • 2012-10-07
    相关资源
    最近更新 更多