如何解决Image需要保持其流开放的事实

时间:2015-04-07 14:20:54

标签: c# .net image stream

我正在为各种文档类型构建一个类库。其中一种类型是包含我们用于处理图像的自定义业务逻辑的图像,包括转换为PDF。我遇到了许多帖子中描述的问题 - 例如herehere - 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);
}

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

1 个答案:

答案 0 :(得分:1)

您可以创建另一个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
}