c# - GDI+ 异常将位图保存到 MemoryStream

标签 c# .net winforms gdi+

我在 Windows 窗体应用程序中遇到问题,当我保存到 MemoryStream 时,Bitmap.Save 失败。这个问题似乎只在一台机器上间歇性地发生(到目前为止),坏消息是在客户现场。我无法在机器上调试,但我得到了一个堆栈跟踪,将问题缩小到一行代码。

这是我的代码的精简版:

byte[] ConvertPixelsToBytes()
{
    // imagine a picture class that creates a 24 bbp image, and has
    // a method to get an unmanaged pixel buffer.
    // imagine it also has methods for getting the width,
    // height, pitch 

    // I suppose this line could return a bad address, but 
    // I would have expected that the Bitmap constructor would have 
    // failed if it was
    System.IntPtr pPixels = picture.GetPixelData();

    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(
            picture.width(),
            picture.height(),
            picture.pitch(),
            System.Drawing.Imaging.PixelFormat.Format24bppRgb,
            pPixels );

    // This line doesn't actually free the memory, but it could be freed in a 
    // background thread
    // (2)
    picture.releasePixelData(pPixels);

    System.IO.MemoryStream memStream = new System.IO.MemoryStream();
    try
    {
        // I don't see how this line could fail, but it does
        // (3)
        bmp.Save(memStream, System.Drawing.Imaging.ImageFormat.Bmp);
        return memStream.ToArray();
    }
   catch(System.Runtime.InteropServices.ExternalException e)
   {
       // e.Message is the very helpful " A generic error occurred in GDI+."
   }
   finally
   {
       memStream.Dispose();
   }
   return new byte[0];
}

知道会发生什么吗?我很确定我的像素缓冲区是正确的,它始终可以在我们的开发/测试机器和其他客户站点上运行。

我对失败的可能原因的看法是

一个。位图构造函数不复制像素数据,而是保留对像素数据的引用,并且由于释放内存而导致保存失败。我没有发现 MSDN 文档在这一点上很清楚,但我假设位图复制像素数据而不是假设它被锁定。

像素数据无效,导致 Save 方法失败。我对此表示怀疑,因为我的像素数据是每像素 24 位,所以据我所知它应该不会无效。

.NET 框架有问题。

如果您对其他可能的失败原因有任何想法,我将不胜感激,这样我就可以向我的应用程序添加额外的检查和日志记录信息,这样我就可以将一些东西发送到现场。

最佳答案

该位图构造函数的 MSDN 文档毫无疑问:

Remarks The caller is responsible for allocating and freeing the block of memory specified by the scan0 parameter, however, the memory should not be released until the related Bitmap is released.

关于c# - GDI+ 异常将位图保存到 MemoryStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/521927/

相关文章:

c# - Webview2 SetVirtualHostNameToFolderMapping 不允许加载本地资源

C# Selenium 3.8 + Firefox 57 作为 Windows 服务运行

C#:如何在 SQL Server 中存储任意对象?

c# - 加载图标/进度条

c# - 使用 BindingSource 绑定(bind)到嵌套属性 - 或者,使实体可绑定(bind)

.net - dotfuscator 会降低执行速度吗?

c# - BackgroundService 未关闭,stoppedToken 从未使用 .net 核心通用主机设置

c# - AddCors 到 .Net Core 的正确顺序是什么?

c# - 生成唯一标识

c# - 泛型,其中 T 是实现接口(interface)的类