当前位置 : 主页 > 编程语言 > c语言 >

c# – 将Bitmap保存到MemoryStream的GDI异常

来源:互联网 收集:自由互联 发布时间:2021-06-25
我在 Windows窗体应用程序中遇到问题,Bitmap.Save在保存到MemoryStream时失败.问题似乎只是间歇性地出现在一台机器上(到目前为止),而坏消息则出现在客户现场.我无法在机器上进行调试,但是
我在 Windows窗体应用程序中遇到问题,Bitmap.Save在保存到MemoryStream时失败.问题似乎只是间歇性地出现在一台机器上(到目前为止),而坏消息则出现在客户现场.我无法在机器上进行调试,但是我得到了一个堆栈跟踪,将问题缩小到一行代码.

这是我的代码的精简版本:

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文档清楚,但我假设Bitmap复制像素数据而不是假设它被锁定.

湾像素数据无效,导致Save方法失败.我怀疑这是因为我的像素数据是每像素24位,所以据我所知它不应该是无效的.

C. .NET框架存在问题.

我很感激任何关于其他可能的失败原因的想法,所以我可以添加额外的检查和记录信息到我的应用程序,所以我可以发送一些东西到现场.

毫无疑问,该Bitmap构造函数的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.

网友评论