如何解决图像需要保持流开放的问题



我正在为各种文档类型构建类库。其中一种类型是图像,它包含我们处理图像的自定义业务逻辑,包括转换为PDF。我遇到了许多文章中描述的问题,例如在这里和这里,System.Drawing.Image.Save构造函数抛出了一个System.Runtime.InteropServices.ExternalException异常,并带有"GDI+中发生了一个通用错误"。

我看到的答案是,输入流需要在Image的整个生命周期中保持打开。我明白了。我遇到的问题是,我的类库不能控制输入流,甚至不能控制是否使用输入流,因为我有两个构造函数。这里有一些代码:

public sealed class MyImage
{
    private System.Drawing.Image _wrappedImage;
    public MyImage(System.IO.Stream input)
    {
        _wrappedImage = System.Drawing.Image.FromStream(input);
    }
    public MyImage(System.Drawing.Image input)
    {
        _wrappedImage = input;
    }
    public MyPdf ConvertToPdf()
    {
        //no 'using' block because ms needs to be kept open due
        // to third-party PDF conversion technology.
        var ms = new System.IO.MemoryStream();
        //System.Runtime.InteropServices.ExternalException occurs here: 
        //"A generic error occurred in GDI+"
        _wrappedImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); 
        return MyPdf.CreateFromImage(ms);
    }
}
public sealed class MyPdf
{
    internal static MyPdf CreateFromImage(System.IO.Stream input)
    {
        //implementation details not important.
        return null;
    }
}

我的问题是:我是否应该保留输入流的副本,以避免客户端在保存我的图像之前关闭流?也就是说,我可以把这个添加到我的类中:

private System.IO.Stream _streamCopy = new System.IO.MemoryStream();

并将构造函数更改为:

public MyImage(System.IO.Stream input)
{
    input.CopyTo(_streamCopy);
    _wrappedImage = System.Drawing.Image.FromStream(_streamCopy);
}

这当然会增加复制流的开销,这并不理想。有更好的方法吗?

您可以创建另一个Bitmap实例:

public MyImage(System.IO.Stream input)
{
    var image = System.Drawing.Image.FromStream(input);
    _wrappedImage = new System.Drawing.Bitmap(image);
    // input stream may now be closed
}

相关内容

  • 没有找到相关文章

最新更新