c# - 如何解决 Image 需要保持其流打开的事实

标签 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;
    }
}

我的问题是:我是否应该保留输入流的副本以避免客户端在我的图像保存之前关闭流的可能性?即,我可以将其添加到我的类(class)中:

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
}

关于c# - 如何解决 Image 需要保持其流打开的事实,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29493873/

相关文章:

r - 添加箭头以指向 R 中比例尺上的值

c# - 如何在没有 GAC 的情况下使用 ApplicationManager 加载对象?

c# - “加载 .CSV 文件之前删除四引号的 C# 脚本任务”

.net - 运行单进程多线程 .NET 应用程序的 Azure 连续 WebJob 的 CPU 利用率较高

c# - 在 EF 查询中指定动态 'OrderBy'/'OrderByDescening' 的最佳方法

android - universal-image-loader 有放大/缩小选项吗?

sql - 如何在SQL Server数据库表列中存储图像

c# - 在 C# 中使用 Outlook 对象发送电子邮件时更改发件人的电子邮件地址和名称

c# - CA1063 修改 Dispose() 使其调用 Dispose(true),然后在当前对象实例上调用 GC.SuppressFinalize,然后返回

c# - 以其他用户身份打开文档